package ip.gui.frames;

import ip.ppm.WritePPM;
import ip.gui.Timer;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import graphics.ImageUtils;
import futils.WriterUtil;

public class SaveFrame extends NegateFrame {
    Menu saveMenu = getMenu("Save");

    private MenuItem saveAsJava_mi =
            addMenuItem(saveMenu, "[T-j]ava...");
    private MenuItem saveAsHexImage_mi =
            addMenuItem(saveMenu, "[T-h]ex image...");
    private MenuItem printIcon_mi =
            addMenuItem(saveMenu, "binary icon...");

    private MenuItem saveAsGif_mi =
            addMenuItem(saveMenu, "[T-g]if...(not 24 bit!)");
    private MenuItem saveAsPPM_mi =
            addMenuItem(saveMenu, "[T-p]pm...");
    private MenuItem saveAsPPMgz_mi =
            addMenuItem(saveMenu, "[T-z]ppm.gz...");

    private MenuItem saveAsShortgz_mi =
            addMenuItem(saveMenu, "[T-s]short.gz...");
    private MenuItem saveAsShortZip_mi =
            addMenuItem(saveMenu, "[T-i]saveAsShortZip...");
    private MenuItem makeTocHtml_mi =
            addMenuItem(saveMenu, "makeTocHtml...");
    private MenuItem print_mi =
            addMenuItem(saveMenu, "print...");


    public void actionPerformed(ActionEvent e) {

        if (match(e, saveAsHexImage_mi)) {
            saveAsHexImage();
            return;
        }
        if (match(e, print_mi)) {
            ImageUtils.print(this);
            return;
        }

        if (match(e, makeTocHtml_mi)) {
            makeTocHtml();
            return;
        }
        if (match(e, saveAsShortZip_mi)) {
            saveAsShortZip();
            return;
        }
        if (match(e, printIcon_mi)) {
            printIcon();
            return;
        }

        if (match(e, saveAsShortgz_mi)) {
            saveAsShortgz();
            return;
        }
        if (match(e, saveAsPPMgz_mi)) {
            saveAsPPMgz();
            return;
        }
        if (match(e, saveAsPPM_mi)) {
            saveAsPPM();
            return;
        }
        if (match(e, saveAsJava_mi)) {
            saveAsJava();
            return;
        }
        if (match(e, saveAsGif_mi)) {
            saveAsGif();
            return;
        }
        super.actionPerformed(e);

    }

    SaveFrame(String title) {
        super(title);
        getFileMenu().add(saveMenu);
    }

    public void saveAsHexImage() {
        graphics.ImageUtils.writeHexImage(getImageBean());
    }

    public static void main(String args[]) {
        System.out.println("Test");
        SaveFrame f = new SaveFrame("save frame");
        f.setVisible(true);
    }


    public void saveAsPPM() {
        String fn = WriterUtil.getSaveFileName("Save as PPM");
        if (fn == null) return;
        saveAsPPM(fn);

    }

    public void saveAsPPM(String fn) {
        WritePPM.doIt(getR(), getG(), getB(), fn);
    }

    public void saveAsPPMgz(String fn) {
        WritePPM wppm = new WritePPM(getImageWidth(), getImageHeight());
        Timer t = new Timer();
        t.start();
        try {
            GZIPOutputStream
                    os = new GZIPOutputStream(
                            new FileOutputStream(fn));
            wppm.writeHeader(os);
            wppm.writeImage(os, getR(), getG(), getB());
            os.finish();
            os.close();
        } catch (Exception e) {
            System.out.println("Save PPM Exception - 2!");
        }
        t.stop();
        t.print(" saveAsPPMgz in ");
    }

    public void saveAsPPMgz() {
        String fn = WriterUtil.getSaveFileName("Save as PPM.gz");
        if (fn == null) return;
        saveAsPPMgz(fn);
    }


    public void saveAsShortZip() {
        String fn = WriterUtil.getSaveFileName("Save ZIP");
        if (fn == null) return;
        saveAsShortZip(fn);
    }

    public void saveAsShortZip(
            String fn) {
        Timer t = new Timer();
        t.start();
        try {
            FileOutputStream
                    fos = new
                            FileOutputStream(fn);
            ZipOutputStream
                    zos = new
                            ZipOutputStream(fos);
            ZipEntry zer =
                    new ZipEntry("r");
            ZipEntry zeg =
                    new ZipEntry("g");
            ZipEntry zeb =
                    new ZipEntry("b");
            zer.setMethod(
                    ZipEntry.DEFLATED);
            zeg.setMethod(
                    ZipEntry.DEFLATED);
            zeb.setMethod(
                    ZipEntry.DEFLATED);
            zos.putNextEntry(zer);
            ObjectOutputStream
                    oos = new
                            ObjectOutputStream(
                                    zos);
            oos.writeObject(getR());
            zos.putNextEntry(zeg);
            oos.writeObject(getG());
            zos.putNextEntry(zeb);
            oos.writeObject(getB());
            oos.close();
            zos.finish();

        } catch (Exception e) {
            System.out.println("Save saveAsShortZip:" + e);
        }
        t.stop();
        t.print(" saveAsOOSZip in ");
    }

    public void saveAsShortZip2(String fn) {
        Timer t = new Timer();
        t.start();
        try {
            FileOutputStream fos = new FileOutputStream(fn);
            ZipOutputStream zos = new ZipOutputStream(fos);
            DataOutputStream dos = new DataOutputStream(zos);
            ZipEntry ze = new ZipEntry("quad0");
            ze.setMethod(ZipEntry.DEFLATED);
            zos.putNextEntry(ze);
            writeHeader(dos);
            writeArray(getR(), dos);
            writeArray(getG(), dos);
            writeArray(getB(), dos);
            zos.close();
            zos.finish();

        } catch (Exception e) {
            System.out.println("Save saveAsShortZip:" + e);
        }
        t.stop();
        t.print(" saveAsShortZip in ");
    }

    public void writeArray(short a[][], DataOutputStream dos)
            throws IOException {
        for (int x = 0; x < getImageWidth(); x++)
            for (int y = 0; y < getImageHeight(); y++)
                dos.writeShort(a[x][y]);
    }

    public void writeHeader(DataOutputStream dos)
            throws IOException {
        dos.writeInt(getImageWidth());
        dos.writeInt(getImageHeight());
    }

    public void saveAsShortgz() {
        String fn = WriterUtil.getSaveFileName("Save gz");
        if (fn == null) return;
        saveAsShortgz(fn);
    }

    public void saveAsShortgz(String fn) {
        Timer t = new Timer();
        t.start();
        try {
            FileOutputStream fos = new FileOutputStream(fn);
            GZIPOutputStream gos = new GZIPOutputStream(fos);
            ObjectOutputStream
                    oos = new
                            ObjectOutputStream(gos);
            oos.writeObject(getR());
            oos.writeObject(getG());
            oos.writeObject(getB());
            oos.close();
            gos.finish();

        } catch (Exception e) {
            System.out.println("Save saveAsShortgz:" + e);
        }
        t.stop();
        t.print(" saveAsShortgz in ");
    }

    public void saveAsGif() {
        System.out.println("Saving as ip.gif...");
        String fn = WriterUtil.getSaveFileName("Save as GIF");
        if (fn == null) return;
        saveAsGif(fn);
    }

    public void saveAsGif(String fn) {
        try {
            ip.vs.WriteGIF.DoIt(
                    getImage(),
                    fn);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void saveAsJava() {
        String fn = WriterUtil.getSaveFileName("Save as Java");
        if (fn == null) return;
        saveAsJava(fn);
    }

    public void saveAsxyz() {
        String fn = WriterUtil.getSaveFileName("Save as GIF");
        if (fn == null) return;
        saveAsxyz(fn);

    }

    public void saveAsxyz(String fn) {
        try {
            FileWriter fos = new FileWriter(fn);
            PrintWriter pw = new PrintWriter(fos);
            saveAsxyz(pw);
            pw.flush();
            fos.close();
        } catch (Exception e) {
        }
    }

    public FileOutputStream getFileOutputStream(String prompt) {
        FileOutputStream fos = null;
        try {
            fos =
                    new FileOutputStream(WriterUtil.getSaveFileName(prompt));
        } catch (IOException e) {
            System.out.println("futil:Could not create file");
        }
        return fos;
    }

    public void makeTocHtml() {
        File dir =
                new File(WriterUtil.getSaveDirectoryName("Enter input directory"));

        String[] files = dir.list(new FileFilter());
        System.out.println(files.length + " file(s):");
        FileOutputStream fos = getFileOutputStream(
                "Enter Save File");
        PrintWriter pw = new PrintWriter(fos);
        pw.println("<HTML>");
        pw.println("<BODY>");
        pw.println("<ul>");
        for (int i = 0; i < files.length; i++)
            pw.println("<P><IMG SRC=" + files[i] + "></P>" +
                    "<a>" + files[i] + "</a><P>");
        //ps.println("<LI><a href = \"" + files[i]+"\">"+
        //  files[i]+"</a><P>");
        pw.println("</ul>");
        pw.println("</BODY>");
        pw.println("</HTML>");
        try {
            fos.close();
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public void saveAsxyz(PrintWriter pw) {
        int y = 0;
        pw.println(0 + " " + 0 + " " + getR()[0][0] + " 0");
        for (int x = 1; x < getImageWidth(); x++) {
            for (y = 0; y < getImageHeight(); y++) {
                pw.println(x + " " + y + " " + getR()[x][y] + " 1");
            }
            y = 0;
            pw.println(x + " " + y + " " + getR()[x][y] + " 0");
        }
    }

    public void saveAsJava(String fn) {
        try {
            FileWriter fos =
                    new FileWriter(fn);
            PrintWriter pw =
                    new PrintWriter(fos);
            saveAsJava(pw);
            pw.flush();
            fos.close();
        } catch (IOException e) {
        }
    }

    public void printIcon() {
        int g;
        System.out.println(

                "public static byte iconName[][] = {\n");

        for (int y = 0; y < getImageHeight(); y++) {
            System.out.print("{");
            for (int x = 0; x < getImageWidth() - 1; x++) {
                if (getR()[x][y] == 0)
                    g = 0;
                else
                    g = 1;
                System.out.print(g + ",");
            }
            if (getR()[getImageWidth() - 1][y] == 0)
                g = 0;
            else
                g = 1;
            System.out.println(g + "},");

        }
        System.out.println("};");

    }

    public void saveAsJava(
            PrintWriter pw) {
        int g;


        pw.println("package ip.gui;\n"
                + "\nclass NumImage {\n"
                + "\tpublic static short gray[][] = {\n");

        for (int y = 0; y < getImageHeight(); y++) {
            pw.print("{");
            for (int x = 0; x < getImageWidth() - 1; x++) {
                g = getR()[x][y];
                if (g < 10)
                    pw.print("  ");
                else if (g < 100) pw.print(" ");
                pw.print(g + ", ");
            }
            pw.println(getR()[getImageWidth() - 1][y] + "},");
            double percent = (y * 1.0 / getImageHeight());

        }
        pw.println("};}");
        System.out.println("Done writing image");

    }

    class FileFilter implements FilenameFilter {
        public boolean accept(File dir, String name) {
            return new File(dir, name).isFile();
        }
    }

}