import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.event.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.text.DateFormat;
import java.awt.geom.*;
import java.awt.image.*;

public class Display extends JFrame {

    public static void main(String[] args) {
	new Display(args[0],false);
    }
    
    class MyCanvas extends JPanel {
	BufferedImage bi = null;
	Dimension size = new Dimension();
	Display owner = null;
	
	private AlphaComposite makeComposite(float alpha) {
	    int type = AlphaComposite.SRC_OVER;
	    return(AlphaComposite.getInstance(type, alpha));
	}
	
	public MyCanvas(BufferedImage bi, Display d) {
	    this.bi = bi;
	    this.owner = d;
	    RescaleOp rescale = new RescaleOp(1.0f, 10, null);
	    size.setSize(bi.getWidth(),bi.getHeight());
	}
	
	public void paintComponent(Graphics g) {
	    int x = (getWidth() - size.width)/2;
	    int y = (getHeight() - size.height)/2;
	    g.drawImage(bi,x,y,this);
	    if (owner.max != owner.absolutemax) {
		Area a = 
		    new Area(new Rectangle2D.Double(0,0,
						    bi.getWidth(),
						    bi.getHeight()));
		for (int i = 0 ; i < owner.freqs.size() ; i++) {
		    if ((owner.freqs.get(i) >= owner.min) && 
			(owner.freqs.get(i) <= owner.max)) {
			a.subtract(owner.areas.get(i));
		    }
		}
		Composite originalComposite = ((Graphics2D)g).getComposite();
		((Graphics2D)g).setComposite(makeComposite(.9f));
		((Graphics2D)g).setPaint(Color.black);
		((Graphics2D)g).fill(a);
		((Graphics2D)g).setComposite(originalComposite);
	    } else if (owner.max == owner.absolutemax) {
		Area a = new Area(new Rectangle2D.Double(0,0,1,1));
		for (int i = 0 ; i < owner.freqs.size() ; i++) {
		    if (owner.freqs.get(i) < owner.min) {
			a.add(owner.areas.get(i));
		    }
		}
		Composite originalComposite = ((Graphics2D)g).getComposite();
		((Graphics2D)g).setComposite(makeComposite(.9f));
		((Graphics2D)g).setPaint(Color.black);
		((Graphics2D)g).fill(a);
		((Graphics2D)g).setComposite(originalComposite);
	    }
	}
	
	public Dimension getPreferredSize() { return size; }
    }
    
    protected int min = 0;
    protected int max = 1000;

    public void setRange(int a, int b, boolean repaint) {
	this.min = (int)Math.min(a,b);
	this.max = (int)Math.max(a,b);
	if (repaint) {
	    mc.repaint();
	}
	setTitle(min + " - " + max);
    }
    
    protected int absolutemin = 0;
    protected int absolutemax = Integer.MIN_VALUE;
    protected ArrayList<Area> areas = new ArrayList<Area>();
    protected ArrayList<Integer> freqs = new ArrayList<Integer>();
    protected MyCanvas mc = null;

    public Display(String image, boolean applet) {
	super("Display");
	if (!applet)
	    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	GridBagLayout gridbag = new GridBagLayout();
	GridBagConstraints c = new GridBagConstraints();
	setLayout(gridbag);
	
	BufferedImage bi = null;
	int start_cond = -1;
	int end_cond = -1;
	try {
	    if (!applet) {
		bi = ImageIO.read(new File(image+".jpg"));
	    } else {
		bi = ImageIO.read(this.getClass().getResourceAsStream(image+".jpg"));
	    }
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
	
	try {
	    BufferedReader br = null;
	    if (!applet) { 
		br = new BufferedReader(new FileReader(image+".coords"));
	    } else {
		br = new BufferedReader(new InputStreamReader(this.getClass().getResourceAsStream(image+".coords")));
	    }

	    while(br.ready()) {
		try {
		    String line = br.readLine();
		    String[] tok = line.split("\\t");
		    //if (tok[1].equals("null")) {
		    //  continue;
		    //} else {
		    //System.out.println(line);
		    //}

		    if (tok[0].equals("inf")) {
			continue;
		    } else if (tok[0].equals("initial")) {
			start_cond = Integer.parseInt(tok[1]);
			end_cond = Integer.parseInt(tok[2]);
			continue;
		    }
		    
		    //int f = (int)Double.parseDouble(tok[0]) * 1000;
		    int f = (int)Double.parseDouble(tok[0]);
		    //int f = (int)(Double.parseDouble(tok[0]) / 1000);
		    if (f > absolutemax) {
			absolutemax = f + 30;
		    }
		    String[] coords = tok[1].split(",");
		    Area a = 
			new Area(new Rectangle2D.Double(Double.parseDouble(coords[0]),
							Double.parseDouble(coords[1]),
							Double.parseDouble(coords[2]),
							Double.parseDouble(coords[3])));
		    areas.add(a);
		    freqs.add(f);
		} catch (Exception ex2) {
		    continue;
		}
	    }
	    br.close();
	} catch (Exception ex) {
	    ex.printStackTrace();
	}
	
	min = absolutemin;
	max = absolutemax;

	JPanel foo = new MyCanvas(bi,this);
	this.mc = (MyCanvas)foo;
	foo.setSize(bi.getWidth(),bi.getHeight());
	System.out.println(bi.getWidth() + " " + bi.getHeight());

	JScrollPane jsp =
	    new JScrollPane(foo,
			    ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
			    ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
	
	if (start_cond == -1) {
	    start_cond = absolutemin;
	} else {
	    start_cond = (int)Math.max(absolutemin,start_cond);
	}
	if (end_cond == -1) {
	    end_cond = absolutemax;
	} else {
	    end_cond = (int)Math.min(absolutemax,end_cond);
	    //	    System.out.println("XXX" + absolutemax + " " + end_cond);
	}
	//	System.out.println(start_cond + " " + end_cond);
	final MultiSlider js = new MultiSlider(MultiSlider.HORIZONTAL,absolutemin,absolutemax,start_cond,end_cond);
	js.setMajorTickSpacing(3600);
	js.setPaintTicks(true);
	MouseListener cl = new MouseInputAdapter() {
		public void mouseReleased(MouseEvent e) {
		    setRange(js.getValueAt(0),js.getValueAt(1),true);
		    //System.out.println(js.getValueAt(0) + " " + js.getValueAt(1));
		}
		//public void mouse
	    };
	js.addMouseListener(cl);
	ChangeListener cl2 = new ChangeListener() {
		public void stateChanged(ChangeEvent e) {
		    setRange(js.getValueAt(0),js.getValueAt(1),false);
		}
	    };
	js.addChangeListener(cl2);
	c.fill = GridBagConstraints.BOTH;
	c.weighty = 1;
	c.weightx = 1;
	c.gridx = 0;
	c.gridy = 0;
	getContentPane().add(jsp,c);
	
	c.fill = GridBagConstraints.HORIZONTAL;
	c.weighty = 0;
	c.gridy = 1;
	getContentPane().add(js,c);
	
	
	setRange(js.getValueAt(0),js.getValueAt(1),true);

	setVisible(true);
	pack();
	setSize(getWidth(),600);
    }
}

