package ip.apurva;

import ip.gui.*;
import ip.gui.frames.SaveFrame;
import ip.gui.frames.TopFrame;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import futils.Futil;
import futils.WriterUtil;

public class MyZipFile extends TopFrame implements ActionListener {
  ImageSequence imgsq = new ImageSequence();
  int count = 1;
  Vector imgvecr = new Vector();
  Vector imgvecg = new Vector();
  Vector imgvecb = new Vector();

  MenuBar mb = getMenuBar();
  Menu Zipmenu = new Menu("Wave Zip");
  MenuItem next_mi = addMenuItem(Zipmenu, "Next Entry");
  MenuItem ForLift_mi = addMenuItem(Zipmenu, "Forward Lifting");
  MenuItem BackLift_mi = addMenuItem(Zipmenu, "BackWard Lifting");
  MenuItem DHT_mi = addMenuItem(Zipmenu, "Split Radix for DHT");


  Menu s_plus_p_menu = new Menu("S + P Xforms");
  MenuItem S_plus_P_forward = addMenuItem(s_plus_p_menu, "S + P Forward");
  MenuItem clearband1 = addMenuItem(s_plus_p_menu, "Clear 1/2 band");
  MenuItem clearband2 = addMenuItem(s_plus_p_menu, "Clear 1/4 band");
  MenuItem clearband3 = addMenuItem(s_plus_p_menu, "Clear 1/8 band");
  MenuItem S_plus_P_inverse = addMenuItem(s_plus_p_menu, "S + P Inverse");

  public void actionPerformed(ActionEvent e) {
    if (match(e, DHT_mi)) {
      dHT_mi();
    }
    if (match(e, S_plus_P_forward)) {
      forward();
    }
    if (match(e, clearband1)) {
      clear_band1();
    }
    if (match(e, clearband2)) {
      clear_band2();
    }
    if (match(e, clearband3)) {
      clear_band3();
    }
    if (match(e, S_plus_P_inverse)) {
      inverse();
    }
    if (match(e, next_mi)) {
      nextentry();
      return;
    }
    if (match(e, ForLift_mi)) {
      forwardzip();
      return;
    }
    if (match(e, BackLift_mi)) {
      backwardzip();
      return;
    }
    super.actionPerformed(e);
  }


  public void dHT_mi() {
    /*DHT_SR dht_mi = new DHT_SR();
    dht_mi.initframe(r,g,b);
    short2Image();*/
  }

  public void forward() {
    Lifting.forwardHaar(getR());
    Lifting.forwardHaar(getG());
    Lifting.forwardHaar(getB());
    SPxform.S_plus_P_Xform(getR());
    SPxform.S_plus_P_Xform(getG());
    SPxform.S_plus_P_Xform(getB());
    short2Image();
  }

  public void clear_band1() {
      clear_band(0, getImageHeight() / 2, getImageWidth(), getImageHeight());
    short2Image();
  }

  public void clear_band2() {
      clear_band(0, getImageHeight() / 4, getImageWidth(), getImageHeight());
    short2Image();
  }

  public void clear_band3() {
      clear_band(0, getImageHeight() / 8, getImageWidth(), getImageHeight());
    short2Image();

  }

  public void clear_band(int x, int y, int x1, int y1) {
    for (int i = x; i < x1; i++) {
      for (int j = y; j < y1; j++) {
        getR()[i][j] = 0;
        getG()[i][j] = 0;
        getB()[i][j] = 0;
      }
    }
  }

  public void inverse() {
    SPxform.inversXform(getR());
    SPxform.inversXform(getG());
    SPxform.inversXform(getB());
    Lifting.backwardHaar(getR());
    Lifting.backwardHaar(getG());
    Lifting.backwardHaar(getB());
    short2Image();
  }

  public void nextentry() {
    System.out.println("" + count);
    setR((short[][]) imgvecr.elementAt(count));
    setG((short[][]) imgvecg.elementAt(count));
    setB((short[][]) imgvecb.elementAt(count));
    Lifting.backwardHaar(getR());
    Lifting.backwardHaar(getB());
    Lifting.backwardHaar(getG());
    short2Image();
      setImageWidth(getR().length);
      setImageHeight(getR()[0].length);
      setSize(getImageWidth(), getImageHeight());
    count--;
    if (count == -1)
      count = imgvecr.size() - 1;
  }

  public void forwardzip() {
    String filename = WriterUtil.getSaveFileName("Save as Zip file");
    try {
      //writing to a zip file
      FileOutputStream fos = new FileOutputStream(filename);
      ZipOutputStream zos = new ZipOutputStream(fos);
      Lifting.forwardHaar(getR());
      Lifting.forwardHaar(getG());
      Lifting.forwardHaar(getB());
      int j,i;
        for (
                i = getImageHeight(), j = 0;
           i > getImageHeight() / 64; i = i / 2, j++) {
        ZipEntry zer = new ZipEntry("r" + i + "");
        ZipEntry zeg = new ZipEntry("g" + i + "");
        ZipEntry zeb = new ZipEntry("b" + i + "");
        zer.setMethod(ZipEntry.DEFLATED);
        zeg.setMethod(ZipEntry.DEFLATED);
        zeb.setMethod(ZipEntry.DEFLATED);
        zos.putNextEntry(zer);
        ObjectOutputStream oos = new ObjectOutputStream(zos);
        //clearing the sub bands by the multiples of 2
            clearQuad(0, i, getImageWidth(), getImageHeight());
        //writing serialized object to the gzip file
        oos.writeObject(getR());
        zos.putNextEntry(zeg);
        oos.writeObject(getG());
        zos.putNextEntry(zeb);
        oos.writeObject(getB());
      }
      zos.finish();
      //applying backward lifting xform to show the last image od the sequence
      Lifting.backwardHaar(getR());
      Lifting.backwardHaar(getB());
      Lifting.backwardHaar(getG());
      short2Image();
    } catch (Exception e) {
      System.out.println("Save as Zip file :" + e);
    }
  }


  public void backwardzip() {
    String filename = Futil.getReadFileName();


    try {
      FileInputStream fos = new FileInputStream(filename);
      ZipInputStream gos = new ZipInputStream(fos);
      ZipEntry ze;
        for (
                int i = getImageHeight();
           i > getImageHeight() / 64; i = i / 2) {
        ze = gos.getNextEntry();
        ze.setMethod(ZipEntry.DEFLATED);
        ObjectInputStream oos = new ObjectInputStream(gos);
        setR((short[][]) oos.readObject());
        imgvecr.addElement(getR());
        ze = gos.getNextEntry();
        ze.setMethod(ZipEntry.DEFLATED);
        setB((short[][]) oos.readObject());
        imgvecg.addElement(getG());
        ze = gos.getNextEntry();
        ze.setMethod(ZipEntry.DEFLATED);
        setG((short[][]) oos.readObject());
        imgvecb.addElement(getB());
            setImageWidth(getR().length);
            setImageHeight(getR()[0].length);
            setSize(getImageWidth(), getImageHeight());
      }
      count = imgvecr.size() - 1;
      Lifting.backwardHaar(getR());
      Lifting.backwardHaar(getB());
      Lifting.backwardHaar(getG());
      short2Image();
      gos.close();
    } catch (Exception e) {
      System.out.println("Open as Zip file :" + e);
    }

  }

  public void clearQuad(int x1, int y1, int x2, int y2) {
    for (int x = x1; x < x2; x++)
      for (int y = y1; y < y2; y++) {
        getR()[x][y] = 0;
        getG()[x][y] = 0;
        getB()[x][y] = 0;
      }
  }

  MyZipFile() {
    super("MyZipFile");
    mb.add(Zipmenu);
    mb.add(s_plus_p_menu);


  }

  public static void main(String args[]) {
     new MyZipFile();
  }

}