package ip.gui.frames;

import futils.Futil;
import gui.Clipper;
import gui.ImageBean;
import gui.ImageBeanInterface;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.ColorModel;
import java.io.File;

import ip.gui.*;
import graphics.ImageUtils;

public class ImageFrame
        extends ShortCutFrame implements ImageFrameInterface {

    private Clipper clipper = new Clipper();

    private ImageBeanInterface ib = new ImageBean();


// No, you can't use bytes, cause
// Java bytes are signed. Yeah, that bites!
    private short r[][];
    private short g[][];
    private short b[][];

    private MenuBar menuBar = new MenuBar();
    private Menu fileMenu = new Menu("File");

    private Menu openMenu = new Menu("Open");
    private MenuItem openGif_mi =
            addMenuItem(getOpenMenu(), "[g]if...");
    private MenuItem default_mi =
            addMenuItem(getOpenMenu(), "[d]efault image");
    private MenuItem revert_mi =
            addMenuItem(getOpenMenu(), "[r]evert");
    private MenuItem fitScreen_mi =
            addMenuItem(getOpenMenu(), "fitScreen");
    CommandLineInterpreter
            cli = new CommandLineInterpreter(this);
    InfoFrame infoFrame
            = new InfoFrame(cli);
    String dir = null;

    public void actionPerformed(ActionEvent e) {

        if (match(e, fitScreen_mi)) {
            ImageUtils.fitScreen(this);
            return;
        }
        if (match(e, openGif_mi)) {
            openGif();
            return;
        }
        if (match(e, default_mi)) {
            grabNumImage();
            return;
        }
        if (match(e, revert_mi)) {
            revert();
            return;
        }
    }

    public ImageFrame(String title) {
        super(title);
        initialize();
    }

    public ImageBeanInterface getImageBean() {
        return ib;
    }


    private void initialize() {
        initMenu();
        grabNumImage();

        show();
        setSize(getImageWidth(), getImageHeight());
        repaint();
    }


    public void grabNumImage() {
        setImageComesFromFile(false);
        setImageWidth(NumImage.getWidth());
        setImageHeight(NumImage.getHeight());
        setR(NumImage.getGray());
        setG(NumImage.getGray());
        setB(NumImage.getGray());
        short2Image();
    }

    private void initMenu() {
        getFileMenu().add(getOpenMenu());
        menuBar.add(getFileMenu());
        setMenuBar(menuBar);
    }

    public void setImageResize(Image i) {
        setImage(i);

        setSize(getImageWidth(), getImageHeight());
        setVisible(true);
        repaint();
    }

    public void setImage(Image i) {
        ib.setImage(i);
        ImageUtils.waitForImage(this, i);
        setImageWidth(i.getWidth(this));
        setImageHeight(i.getHeight(this));
        image2Short();
    }

    public void setImageNoShort(Image img) {
        setImage(img);
        ImageUtils.waitForImage(this, img);
        setImageWidth(img.getWidth(this));
        setImageHeight(img.getHeight(this));
    }

    public Image getImage() {
        ImageUtils.waitForImage(this, ib.getImage());
        return ib.getImage();
    }

    public String getFileName() {
        return ib.getFile() + "";
    }

    public Clipper getClipper() {
        return clipper;
    }


    /**
     short2Image - turn 3 short arrays, r, g and b into an image.
     */
    public void short2Image() {
        clipper.setClipped(false);
        setImageWidth(getR().length);
        setImageHeight(getR()[0].length);
        Image i = ImageUtils.getImage(getR(), getG(), getB());
        setImageNoShort(i);
        Rectangle r = getBounds();
        repaint(0, 0, r.width, r.height);
        if (clipper.isClipped())
            Print.println(
                    "warning: clipped image. min max =" +
                    clipper.getMin() + "," +
                    clipper.getMax());
    }

    public void pels2Image(int pels[]) {
        setImageWidth(getR().length);
        setImageHeight(getR()[0].length);
        Image i = ImageUtils.pelsToImage(pels, getImageWidth(), getImageHeight());
        setImageNoShort(i);
        Rectangle r = getBounds();
        repaint(0, 0, r.width, r.height);
    }

    /**
     image2Short - takes the private Image instance and
     makes 3 short arrays, r, g and b.
     */
    public void image2Short() {
        if (getImage() == null) return;
        if (getImageWidth() < 0) return;
        if (getImageHeight() < 0) return;
        setR(new short[getImageWidth()][getImageHeight()]);
        setG(new short[getImageWidth()][getImageHeight()]);
        setB(new short[getImageWidth()][getImageHeight()]);

        ImageUtils.pelsToShort(getR(), getG(), getB(),
                ImageUtils.imageToPels(
                        getImage(),
                        getImageWidth(),
                        getImageHeight()),
                getImageWidth(), getImageHeight());
    }


    public void openGif() {
        String fn =
                Futil.getReadFileName();
        if (fn == null) return;
        openGif(fn);
    }

    public void setFtpFileName(String _fn) {
        setFileName(_fn);
        setImageComesFromFile(false);
    }

    public void setFileName(String _fn) {
        File f = new File(_fn);
        if (!f.exists()) return;
        ib.setFile(f);
        infoFrame.println(
                "File:" + _fn +
                "\nis " + f.length() + " bytes long");
        setImageComesFromFile(true);

    }

    public void openGif(String fn) {
        File f = new File(fn);
        if (!f.exists()) {
            grabNumImage();
            return;
        }

        setFileName(fn);
        setImage(Toolkit.getDefaultToolkit().getImage(
                getFileName()));
        setImageResize(getImage());
        setImageComesFromFile(true);
    }

    public void revert() {
        if (isImageComesFromFile()) {
            getImageFromFile();
        } else
            grabNumImage();

    }

    private void getImageFromFile() {
        if (getFileName() == null)
            openGif();
        else {
            setImage(Toolkit.getDefaultToolkit().getImage(getFileName()));
            setImageResize(getImage());
        }
    }

    public void revertNoResize() {
        Toolkit tk = Toolkit.getDefaultToolkit();
        if (isImageComesFromFile()) {
            if (getFileName() == null)
                openGif();
            else {
                setImage(tk.getImage(getFileName()));
                setImage(getImage());
            }
        } else
            grabNumImage();

    }

    // Takes a packed RGB model and makes
    // the short arrays
    public void int2Short(int pels[]) {
        Print.println("The width and height are"
                + getImageWidth() + "," + getImageHeight());
        setR(new short[getImageWidth()][getImageHeight()]);
        setG(new short[getImageWidth()][getImageHeight()]);
        setB(new short[getImageWidth()][getImageHeight()]);
        int i = 0;
        for (int x = 0; x < getImageWidth(); x++)
            for (int y = 0; y < getImageHeight(); y++) {
                i = x + y * getImageWidth();
                getB()[x][y] = (short) getCm().getBlue(pels[i]);
                getG()[x][y] = (short) getCm().getGreen(pels[i]);
                getR()[x][y] = (short) getCm().getRed(pels[i]);
            }
    }


    public static void main(String args[]) {
        ImageFrameInterface imgFrm =
                new ImageFrame("Image Frame");
        imgFrm.openGif();
    }

    public void paint(Graphics g) {
        if (getImage() != null) {
            Rectangle r = getBounds();
            g.drawImage(getImage(), 0, 0, r.width, r.height,
                    this);
        }
    }

    public int getImageWidth() {
        return ib.getImageWidth();
    }

    public void setImageWidth(int imageWidth) {
        ib.setImageWidth(imageWidth);
    }

    public int getImageHeight() {
        return ib.getImageHeight();
    }

    public void setImageHeight(int imageHeight) {
        ib.setImageHeight(imageHeight);
    }

    public boolean isImageComesFromFile() {
        return ib.isFromFile();
    }

    public void setImageComesFromFile(boolean imageComesFromFile) {
        ib.setFromFile(imageComesFromFile);
    }

    public ColorModel getCm() {
        return ib.getCm();
    }

    public Menu getFileMenu() {
        return fileMenu;
    }

    public void setFileMenu(Menu fileMenu) {
        this.fileMenu = fileMenu;
    }

    public Menu getOpenMenu() {
        return openMenu;
    }

    public void setOpenMenu(Menu openMenu) {
        this.openMenu = openMenu;
    }

    public short[][] getR() {
        return r;
    }

    public void setR(short[][] r) {
        this.r = r;
    }

    public short[][] getG() {
        return g;
    }

    public void setG(short[][] g) {
        this.g = g;
    }

    public short[][] getB() {
        return b;
    }

    public void setB(short[][] b) {
        this.b = b;
    }


}