import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 * Esta clase maneja la visualizacion y nivel de agua en los estanques
 * @author Francisco Cabezas
 * @author Manuel Gallardo
 */

public class Tank extends Equipment {

	public Tank(Point _position, PlantView v, int id){
		position=_position;
		view= v;
		x_t=0.25f;
		h_t=H/2;
		boundary=new GeneralPath();
		boundary.moveTo(position.x+boundaryX[0], position.y+boundaryY[0]);
		boundary.lineTo(position.x+boundaryX[1], position.y+boundaryY[1]);
		boundary.lineTo(position.x+boundaryX[2], position.y+boundaryY[2]);
		boundary.quadTo(position.x+boundaryX[3], position.y+boundaryY[3],
				position.x+boundaryX[4], position.y+boundaryY[4]);
		boundary.lineTo(position.x+boundaryX[5], position.y+boundaryY[5]);
		boundary.lineTo(position.x+boundaryX[6], position.y+boundaryY[6]);
		boundary.quadTo(position.x+boundaryX[7], position.y+boundaryY[7],
				position.x+boundaryX[8], position.y+boundaryY[8]);
		boundary.lineTo(position.x+boundaryX[9], position.y+boundaryY[9]);
		boundary.moveTo(position.x+boundaryX[10], position.y+boundaryY[10]);
		fluid= new Rectangle(position.x+boundaryX[0], position.y-(int)h_t, (int)W+5, (int)H);
		fluidOut=new Rectangle(position.x+boundaryX[3], position.y, 5, 20);
		
                gui=new Box(BoxLayout.Y_AXIS);  //Se cambia el eje X por el eje Y, para que se vea vertical
		
                JLabel label= new JLabel("h estanque #"+id+" "); // define h_1 y h_2
		gui.add(label);
		level= new SpinnerNumberModel(h_t, 0, H, 1);
		level.addChangeListener(new ChangeListener(){
			public synchronized void stateChanged(ChangeEvent e){
				SpinnerNumberModel sn=(SpinnerNumberModel)e.getSource();
				h_t=sn.getNumber().floatValue();
				view.repaint();
			}
		});
		JSpinner spinner = new JSpinner(level);
		gui.add(spinner);
		label= new JLabel("Valvula estanque #"+id+" ");
		gui.add(label);
		valve= new SpinnerNumberModel(x_t, 0.0, 1.0, 0.05);
		valve.addChangeListener(new ChangeListener(){
			public void stateChanged(ChangeEvent e){
				SpinnerNumberModel sn=(SpinnerNumberModel)e.getSource();
				x_t=sn.getNumber().floatValue();
				view.repaint();
			}
		});
		spinner = new JSpinner(valve);
		gui.add(spinner);
	}
	public void paint(Graphics2D g2d){  // esta en la clase abs Equipment
		fluid.setLocation((int)fluid.getX(),position.y-(int)h_t);
		fluidOut.setSize((int)fluidOut.getWidth(),(int)((Math.sqrt(h_t/H)*x_t)*60));
		Color c=g2d.getColor();
		g2d.setColor(Color.black);
		g2d.draw(boundary);
                
		g2d.setColor(Color.blue);
		Shape s=g2d.getClip();
		g2d.setClip(boundary);
		g2d.clip(fluid);
		g2d.fill(g2d.getClip());
		g2d.setClip(s);
		g2d.fill(fluidOut);
		g2d.setColor(c);
	}
        
  
	public float getLevel() {
		return h_t;
	}
	public void setOutValve(float x){
		x_t=x;
		valve.setValue(new Float(x_t));
	}
	public float getOutValve(){
		return x_t;
	}
	public void setReceiver(Tank t){
		receiver=t;
	}
	public Box getGUI(){    // esta en la clase abs Equipment
		return gui;
	}

	public void addVol(float vol){
		h_t+=vol/A;
		if (h_t>H) h_t=H;
		level.setValue(new Float(h_t));
	}
	public synchronized void timeTick(float dt){    // esta en la clase abs Equipment
		float dv=(float)(K*x_t*Math.sqrt(h_t)*dt);
		if (receiver!=null)
			receiver.addVol(dv);
		h_t-=dv/A;
		if (h_t<0) h_t=0;
		level.setValue(new Float(h_t));
	}
	public static final float H=100;
	public static final float W=75;
	private final float A= (float)Math.PI*W*W/4;
	private static final float K=400;
	private final int[] boundaryX={0,0,(int)W-5,(int)W,(int)W,(int)W+5,(int)W+5,(int)W+5,(int)W,(int)W,0};
	private final int[] boundaryY={(int)-H,0,0,0,5,5,0,-5,-5,(int)-H,(int)-H};
	private float x_t;	
	private float h_t;
	private Tank receiver;
	private Point position;
	private Rectangle fluid;
	private Rectangle fluidOut;	
	private GeneralPath boundary; 
	private PlantView view;
	private Box gui;
	private SpinnerNumberModel level, valve;
}
