package ip.gui;

import futils.Futil;
import futils.WriterUtil;

import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

import ip.gui.frames.SaveFrame;

public class ImageSequence {
    private int index = 0;
    private int width = 0;
    private int height = 0;
    private Vector imageVector =
            new Vector();

    public int getSize() {
        return imageVector.size();
    }

    public void setWidth(int w) {
        width = w;
    }

    public void setHeight(int h) {
        height = h;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public void setIndex(int i) {
        index = i;
    }

    public void add(Image img) {
        imageVector.addElement(img);
    }

    public Image pels2Image(
            int pels[], int w, int h) {
        Toolkit tk = Toolkit.getDefaultToolkit();
        return tk.createImage(
                new MemoryImageSource(
                        w,
                        h,
                        ColorModel.getRGBdefault(),
                        pels, 0,
                        w));
    }

    public int[] toPels(Image img) {
        int pels[] = new int[width * height];
        PixelGrabber grabber =
                new PixelGrabber(
                        img, 0, 0,
                        width,
                        height,
                        pels, 0,
                        width);
        try {
            grabber.grabPixels();
        } catch (InterruptedException e) {
        }
        ;
        return pels;
    }

    public void open() {
        open(
                Futil.getReadFileName());
    }

    public void open(URL url) {
        try {
            open(url.openStream());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Image next() {
        Image img = (Image)
                imageVector.elementAt(index++);
        if (index ==
                imageVector.size() - 1)
            index = 0;
        return img;
    }

    public Image elementAt(int i) {
        return (Image)
                imageVector.elementAt(i);
    }

    public int[][] toPels() {
        int n = getSize();
        int pels[][] = new int[n][];
        for (int i = 0; i < n; i++)
            pels[i] = toPels(i);
        return pels;
    }

    public int[][] forwardHaar() {
        int pels[][] = toPels();
        for (int i = 0; i < pels.length; i++)
            Lifting.forwardHaar(pels[i], pels.length);
        resetImages();
        for (int i = 0; i < pels.length; i++)
            add(pels2Image(pels[i], width, height));
        return pels;
    }

    public int[][] backwardHaar() {
        int pels[][] = toPels();
        Lifting.backwardHaar(pels);
        resetImages();
        for (int i = 0; i < pels.length; i++)
            add(pels2Image(pels[i], width, height));
        return pels;
    }

    public void resetImages() {
        imageVector = new Vector();
        index = 0;
    }

    public int[] toPels(int i) {
        return
                toPels(elementAt(i));
    }

    public void save(String fn) {
        try {
            FileOutputStream fos =
                    new FileOutputStream(fn);
            GZIPOutputStream gos =
                    new GZIPOutputStream(fos);
            ObjectOutputStream oos =
                    new ObjectOutputStream(gos);
            save(oos);
            oos.close();
            gos.finish();
            gos.close();

        } catch (IOException e) {
            System.out.println(e);
        }
        System.out.println("done");
    }

    public void save(
            ObjectOutputStream oos)
            throws IOException {
        oos.writeInt(width);
        oos.writeInt(height);
        System.out.println(width);
        System.out.println(height);
        oos.writeInt(getSize());
        for (int i = 0; i < getSize(); i++)
            oos.writeObject(toPels(i));
    }

    public void save() {
        save(
                WriterUtil.getSaveFileName(
                        "*.imgs"));
    }

    public void open(InputStream
            is)
            throws IOException, ClassNotFoundException {
        GZIPInputStream gis =
                new GZIPInputStream(is);
        ObjectInputStream ois
                = new ObjectInputStream(gis);
        open(ois);
        ois.close();
    }

    public void open(String fn) {
        imageVector = new Vector();
        try {
            FileInputStream fis = new FileInputStream(fn);
            GZIPInputStream gis = new GZIPInputStream(fis);
            ObjectInputStream ois = new ObjectInputStream(gis);
            open(ois);
            ois.close();
            //gis.finish();

        } catch (Exception e) {
            System.out.println(e);
        }
        System.out.println("done reading images");

    }

    public void open(
            ObjectInputStream ois)
            throws IOException,
            ClassNotFoundException {

        width = ois.readInt();
        height = ois.readInt();
        int numberOfImages = ois.readInt();
        for (int i = 0;
             i < numberOfImages;
             i++)
            add(
                    pels2Image(
                            (int[])
                    ois.readObject(),
                            width, height));
    }
}