package ip.gui.frames;

// here is the frame that should always be on
// top.
// To add frames, insert them below TopFrame.
// 8/23/98 - DL

import futils.Futil;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.File;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;

import ip.gui.*;
import math.Mat;
import math.MatFloat;

public class TopFrame
        extends WaveletFrame
        implements ip.graphics.Docjava3d {


    private Menu reflectionMenu = getMenu("cutils.reflection");
    private Menu diffractionMenu = getMenu("diffraction");
    private Menu movieMenu = getMenu("movies");
    private Menu utilMenu = getMenu("utilities");
    private Menu effectsMenu = getMenu("effects");

    private MenuItem processDiffractionImages_mi =
            addMenuItem(diffractionMenu, "process linear images");
    private MenuItem processDiffractionImage_mi =
            addMenuItem(diffractionMenu, "process edge image");
    private MenuItem processCylindrical_mi =
            addMenuItem(diffractionMenu, "process cylindrical images");
    private MenuItem threeDImageCylindrical_mi =
            addMenuItem(diffractionMenu, "display dgt file");


    private MenuItem animateFrame_mi =
            addMenuItem(movieMenu, "Show Animate Frame");
    private MenuItem makeMovie_mi =
            addMenuItem(movieMenu, "makeMovie");

    private MenuItem saveAsxyz_mi =
            addMenuItem(saveMenu, "save as x y z c");

    private MenuItem threeDImage_mi =
            addMenuItem(effectsMenu, "threeDImage");
    private MenuItem mandelbrot_mi =
            addMenuItem(effectsMenu, "mandelbrot");

    private MenuItem html_mi =
            addMenuItem(utilMenu, "[T-h]tml generator...");
    private MenuItem prototype_mi =
            addMenuItem(utilMenu, "prototype generator...");
    private MenuItem benchMark_mi =
            addMenuItem(utilMenu, "bench mark");
    private MenuItem rename_mi =
            addMenuItem(utilMenu, "rename");
    private MenuItem ls_mi =
            addMenuItem(utilMenu, "ls");
    private MenuItem commandLine_mi =
            addMenuItem(utilMenu, "command line");
    private MenuItem goslab_mi =
            addMenuItem(utilMenu, "GOSLAB");
    private MenuItem printMethods_mi =
            addMenuItem(reflectionMenu, "printMethods");
    private MenuItem systemInfo_mi =
            addMenuItem(reflectionMenu, "systemInfo");

    public TopFrame(String title) {
        super(title);
        init();
    }

    public TopFrame(String title, Image img) {
        super(title);
        init();
        super.setImageResize(img);
    }

    public TopFrame(String title,
                    short _r[][],
                    short _g[][],
                    short _b[][]) {
        super(title);
        init();
        setR(_r);
        setG(_g);
        setB(_b);
        setSize(getR().length, getR()[0].length);
        short2Image();
    }

    private void init() {
        utilMenu.add(reflectionMenu);
        getFileMenu().add(effectsMenu);
        getFileMenu().add(diffractionMenu);
        getFileMenu().add(movieMenu);
        getFileMenu().add(utilMenu);
        commandLine();
        positionInfoFrame();

    }

    private static String args[] =
            {""};

    public void cpus() {
        rmi.rmiimage.CPUArrayFrame.main(args);
    }

    public static void mandelbrot() {
        String title = "OpenLifting";
        ip.raul.MyOpenFrame of =
                new ip.raul.MyOpenFrame(title);
        of.setVisible(true);
        of.setSize(64, 64);
        of.mandelbrot();
    }

    public void tracer() {
        Timer t = new Timer();
        t.start();
        graphics.tracer.Scene scene
                = new graphics.tracer.Scene(
                        new Dimension(getImageWidth(), getImageHeight()));
        pels2Image(
                scene.render());
        t.print("render done");
    }

    public void animateMorph() {
        ip.raul.MorphLog.main(args);
    }

    public void play() {
        sound.UlawCodec.playFromFile();
    }

    public void goslab() {
        new
                gui.goslab.GOSLAB();

    }

    public static void imageMorph() {
        ip.hak.ImageMorph.main(args);
    }

    public static void sketchFrame() {
        graphics.draw2d.SketchFrame.main(args);
    }

    public static void spiral() {
        graphics.draw2d.Spiral.main(args);
    }

    public void preview2d() {
        graphics.tracer.Scene scene
                = new graphics.tracer.Scene(
                        new Dimension(getImageWidth(), getImageHeight()));
        scene.preview();
    }

    public void preview3d() {
        //ip.raul.Application.main(args);
    }

    public void quote() {

        String args[] =
                {""};
        net.QuoteFrame.main(args);
    }

    public void positionInfoFrame() {
        Rectangle r = getBounds();
        Dimension d = r.getSize();
        infoFrame.setLocation(0, 2 * d.height);
    }

    public static void main(String args[]) {
        String title = "Kahindu by D. Lyon";
        if (args.length == 1)
            title = args[0];
        TopFrame tf =
                new TopFrame(title);
        tf.setVisible(true);
        tf.setSize(64, 64);

    }

    public void actionPerformed(ActionEvent e) {
        if (match(e, mandelbrot_mi)) {
            mandelbrot();
            return;
        }
        if (match(e, goslab_mi)) {
            goslab();
            return;
        }
        if (match(e, prototype_mi)) {
            prototype();
            return;
        }
        if (match(e, html_mi)) {
            html();
            return;
        }
        if (match(e, animateFrame_mi)) {
            af.setVisible(true);
            return;
        }
        if (match(e, commandLine_mi)) {
            commandLine();
            return;
        }
        if (match(e, processCylindrical_mi)) {
            processCylindrical();
            return;
        }
        if (match(e, threeDImageCylindrical_mi)) {
            threeDImageCylindrical();
            return;
        }
        if (match(e, benchMark_mi)) {
            benchMark();
            return;
        }
        if (match(e, printMethods_mi)) {
            printMethods();
            return;
        }
        if (match(e, rename_mi)) {
            rename();
            return;
        }
        if (match(e, makeMovie_mi)) {
            makeMovie();
            return;
        }
        if (match(e, saveAsxyz_mi)) {
            saveAsxyz();
            return;
        }
        if (match(e, processDiffractionImages_mi)) {
            processDiffractionImages();
            return;
        }
        if (match(e, processDiffractionImage_mi)) {
            processDiffractionImage();
            return;
        }
        if (match(e, ls_mi)) {
            ls();
            return;
        }
        if (match(e, threeDImage_mi)) {
            threeDImage();
            return;
        }
        if (match(e, systemInfo_mi)) {
            systemInfo();
            return;
        }
        super.actionPerformed(e);
    }

    public void processDiffractionImage() {
        erode(getKh());
        //System.out.println("Erode h done...");
        roberts2();
        //System.out.println("Robert2 done...");
        close(getKsquare());
        //System.out.println("Close square done...");
        skeleton();
        //System.out.println("Skeleton done...");
        //double ip[]={16.0, 16.0, 16.0, 16.0, 0.0};
        //doit(ip);

    }

    public void prototype() {
        ip.graphics.ProtoType.main(args);
    }

    public void html() {
        gui.htmlconverter.HtmlGenerator.main(args);
    }

    public void threeDImageCylindrical() {
        float radius[][] = new float[20][50];
        MatFloat mf = new MatFloat(radius);
        String fn = Futil.getReadFileName();
        mf.readAsgz(fn);
        radius = mf.f;

        graphics.idx.Application.image3D(getImage(), radius);
    }

    public String[] getFileNames() {
        FileDialog fd = new FileDialog(new Frame(), "select file");
        fd.show();
        dir = fd.getDirectory();
        FileFilter files = new FileFilter();
        File f = new File(dir);
        String fn[] = f.list(files);
        for (int i = 0; i < fn.length; i++)
            fn[i] = dir + fn[i];
        return fn;
    }

    public void processCylindrical() {
        //x and y are used as looping variables when parsing each image
        int y = 0;
        int x = 0;
        int steps = 35;//the number of y values from an image (taken at equal intervals)
        int NumberOfImages;
        String files[] = getFileNames();
        NumberOfImages = files.length;
        float radius[][] = new float[steps][NumberOfImages];
        //according to the next four variables,
        //the images will only be searched in the specified region
        int ymin = 0;
        int ymax = 234;
        int xmin = 140;
        int xmax = 200;

        //the next two variables, after parsing all the images,
        //will hold the most left and most right values of the radius.
        //useful for scaling the object
        float maxr = 0;
        float minr = 10000;
        System.out.println("ymin=" + ymin);
        System.out.println("ymax=" + ymax);
        System.out.println("xmin=" + xmin);
        System.out.println("xmax=" + xmax);

        for (int i = 0; i < NumberOfImages; i++) {
            openGif(files[i]);
            processDiffractionImage();
            System.out.println(i);
            try {
                for (y = 0; y < steps; y++) {
                    for (x = xmin; x < xmax; x++) {
                        if (getR()[x][ymin + y * ((ymax - ymin) / steps)] == 0) continue;
                        radius[y][i] = x;
                        if (x > maxr) maxr = x;
                        if (x < minr) minr = x;
                        break;
                    }
                    if (x == xmax) radius[y][i] = 0;
                }
            } catch (Exception e) {
                System.out.println(e + "x,y=" + x + "," + y);
            }
        }

        //scaling section
        //values of r[][] less than zero will not be triangulated later on
        System.out.println("min=" + minr);
        System.out.println("max=" + maxr);
        for (int i = 0; i < NumberOfImages; i++) {
            for (y = 0; y < steps; y++) {
                radius[y][i] = radius[y][i] - minr;
                radius[y][i] = ((radius[y][i]) / (maxr - minr));
            }
        }

        MatFloat mf = new MatFloat(radius);
        String fn = mf.getSaveFileName("flt.gz file");
        mf.saveAsgz(fn);
        mf.readAsgz(fn);
        graphics.idx.Application.image3D(getImage(), radius);
    }

    public void processMovieImage(double t) {
        System.out.println("t=" + t);
        polarTransform(0.5, t * 2);
        fishEye((getImageWidth() / 2),
                (getImageHeight() / 2), 2 * t + 2.1);
        sqrt(t);
    }

    AnimateFrame af = new AnimateFrame();

    public void makeMovie() {
        String files[] = getFileNames();
        for (int i = 0; i < files.length; i++) {
            openGif(files[i]);
            processMovieImage(i / (double) files.length);
            int outFileNumber = i + files.length;
            String outFileName = dir + "eclaire" + outFileNumber + ".GIF";
            System.out.println("reading:" + files[i]);
            System.out.println("writing:" + outFileName);
            saveAsGif(outFileName);
        }
    }

    public void processDiffractionImages() {
        int y = 0;
        int x = 0;
        String files[] = getFileNames();
        short zimage[][] = new short[files.length][256];
        for (int i = 0; i < files.length; i++) {
            openGif(files[i]);
            processDiffractionImage();
            try {
                for (y = 0; y < getImageHeight(); y++)
                    for (x = 0; x < getImageWidth(); x++) {
                        if (getR()[x][y] == 0) continue;
                        zimage[i][y] = (short) x;
                    }
            } catch (Exception e) {
                System.out.println(e + "x,y=" + x + "," + y);
            }
        }
        setR(Mat.copyArray(zimage));
        setImageWidth(files.length);
        int height1 = getImageHeight();
        setImageHeight(height1);
        copyRedToGreenAndBlue();
        short2Image();
    }

    public void ls() {
        String files[] = getFileNames();
        for (int i = 0; i < files.length; i++) {
            File f = new File(files[i]);
            String fn = f.getName() + "\t\t\t";
            if (f.canRead())
                fn = fn + "r";
            else
                fn = fn + "-";
            if (f.canWrite())
                fn = fn + "w";
            else
                fn = fn + "-";
            fn = fn + "\t" + f.length();
            System.out.println(fn);
        }
    }

    public void rename() {
        String files[] = getFileNames();
        for (int i = 0; i < files.length; i++) {
            File f = new File(files[i]);
            String fn = f.getName();
            File f2 = new File(dir + "d" + fn);
            if (fn.length() > 13)
                f.renameTo(f2);
        }
    }

    public void systemInfo() {
        System.out.println(getTitle());
        printProp("java.version");
        printProp("java.class.version");
        getOsArch();
        printProp("os.name");
        printProp("os.version");
        printProp("java.vendor");
        printProp("java.vendor.url");
        getUserHome();
        getUserDir();
        getJavaHome();
        getJavaClassPath();

    }

    private void getOsArch() {
        printProp("os.arch");
        free();
    }

    private void getJavaClassPath() {
        printProp("java.class.path");
    }

    private void getJavaHome() {
        printProp("java.home");
    }

    private void getUserDir() {
        printProp("user.dir");
    }

    private void getUserHome() {
        printProp("user.home");
    }

    public void printProps() {
        Properties props = System.getProperties();
        for (Enumeration e =
                props.propertyNames(); e.hasMoreElements();) {
            String key = (String) e.nextElement();
            infoFrame.println(key + " = " + (String) (props.get(key)));
        }
    }

    public static void printProp(String p) {
        System.out.println(p + ":" + System.getProperty(p));
    }

    public void threeDImage() {
        if (getChild() == null) {
            image3d(getImage(), getR());
            return;
        }
        image3d(getChild().getImage(), getR());

    }

    public void image3d(Image img, short i[][]) {
        graphics.idx.Application.image3D(img, i);
    }

    public void printMethods(Method methods[]) {
        for (int i = 0; i < methods.length; i++) {
            infoFrame.print(methods[i] + "\t");
            if (i % 4 == 0) System.out.println();
        }
    }

    public void printMethodNames(Method ma[]) {
        int length = 0;
        for (int i = 0; i < ma.length; i++) {
            infoFrame.print(ma[i].getName() + "   ");
            length += ma[i].getName().length() + 1;
            if (length > 70) {
                infoFrame.print("\n..");
                length = 0;
            }
        }
        infoFrame.println();
    }

    public void drawTest() {
        String args[] = {""};
        graphics.draw2d.DrawTest.main(args);
    }

    public Method[] getMethodsWithNoArguments() {
        Vector v = new Vector();
        Class c = this.getClass();
        Method ma[] = c.getMethods();
        for (int i = 0; i < ma.length; i++) {
            Class ca[] = ma[i].getParameterTypes();
            if (ca.length == 0)
                v.addElement(ma[i]);
        }
        ma = new Method[v.size()];
        for (int i = 0; i < v.size(); i++)
            ma[i] = ((Method) v.elementAt(i));
        return ma;
    }

    public void printMethods() {
        printMethodNames(getMethodsWithNoArguments());
    }


    public void commandLine() {
        free();
        println("Type 'help' to get help");

    }

    Timer t = new Timer();

    public void startTime() {
        t.start();
    }

    public void printTime() {
        println("Command executed in " +
                t.getElapsedTime() +
                " seconds");
    }

    public void free() {
        futils.Exec e = new futils.Exec();
        println(e.getPrintRamString());
    }

    /* The following will not compile on a mac!

    public void printAllMethods() {
       Class c = this.getClass();
       printMethodNamesAndParameters(getAllMethods());

    }
     public void printMethodNamesAndParameters(Method ma[]) {

       for (int i=0; i < ma.length; i++) {
           Class ca[] = ma[i].getParameterTypes();
           infoFrame.print(ma[i].getName()+"(");

           if (ca != null)  {
             for (int j=0; j < ca.length;j++) {
               infoFrame.print(ca[j].getName()+",");
               if (ca[j] instanceof Object)
                   printMethodNamesAndParameters(ca[j].getMethods());
             }

             infoFrame.print(")");
           }
           infoFrame.print("\n..");
       }
    }
    */
    public Method[] getAllMethods() {
        Vector v = new Vector();
        Class c = this.getClass();
        Method ma[] = c.getMethods();
        for (int i = 0; i < ma.length; i++)
            v.addElement(ma[i]);

        ma = new Method[v.size()];
        for (int i = 0; i < v.size(); i++)
            ma[i] = ((Method) v.elementAt(i));
        return ma;
    }

    public void rmic() {
        rmi.rmiimage.Compile.rmic();
        println("stubs created");
    }

    public void server() {
        println("running server...ta da!");
        rmi.rmiimage.Server.run();
    }

    public void help() {
        infoFrame.println(
                "Kahindu is Shareware. To register send a check for $30 to:\n" +
                "Douglas Lyon\nCSE Dept.\nUniversity of Bridgeport\n" +
                "Bridgeport CT 06601\n" +
                "Please add $5 for each additional computer that\n" +
                "Kahindu is installed on\n" +
                "Further upgrades are $10\n" +
                "Consulting and teaching services are available\n\n" +
                "Web Page: <http://www.DocJava.com> \n" +
                "Internet: lyon@DocJava.com\n" +
                "Those people sending in the shareware fee get\n" +
                "The latest version and an instruction manual\n" +
                "\nType a method name and carrage return\n" +
                "and the method will be invoked\n" +
                "'quit' - exits from CLI\n" +
                "'printMethods' will print the methods\n"
        );
    }

    public void print(String s) {
        infoFrame.print(s);
    }

    public void println(String s) {
        infoFrame.println(s);
    }

    public void benchMark() {
        BenchMark bm = new BenchMark();
        bm.run(this);
    }
}