import ij.*;
import ij.io.*;
import ij.process.*;
import ij.gui.*;
import ij.text.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.image.*;
import ij.plugin.frame.*;
import java.io.*;
import java.util.*;
import javax.swing.event.*;
import java.text.*;
import ij.plugin.Duplicator;

@SuppressWarnings( "deprecation" )
public class Plugin_Curve extends PlugInFrame  implements ActionListener, ItemListener, MouseMotionListener, MouseListener{
	
	private ImagePlus imp, imp_original;
	private ImageProcessor ip;
	private int type;
	private Panel panel;
	private Button buttonRc, buttonRa, buttonApply;
	private Checkbox cAll, cRed, cGreen,cBlue, cLinear, cSpline;
	private CheckboxGroup channel, interpolation;
	private PlotPC plot;
	private Label lChannel, lMouse, lInterpolation;
	private long time;
	private int currentChannel = 0;
	private Channel[] channelP = new Channel[4];
	public Plugin_Curve() {
		super("Plugin Curve");
		
	}
      
	public void run(String arg){

		imp = WindowManager.getCurrentImage();
		if (imp==null) {
			IJ.beep();
			IJ.showStatus("No image");
           		IJ.noImage();
			return;
		}
		
		imp_original = new Duplicator().run(imp);		ip = imp.getProcessor();
        	type = imp.getType(); 
		initPC();
		setSize(new Dimension(450,320));
		GUI.center(this);
		show();
	}

	private void initPC(){
		setResizable(false);
		Color color=new Color(237,237,237);  
  


		plot = new PlotPC();
		panel = new Panel();
		panel.setBackground(color);

		buttonApply = new Button("Apply");
		buttonRc = new Button("Restore Channel");
		buttonRa = new Button("Restore All");

		channel = new CheckboxGroup();
		cAll = new Checkbox("All", channel, true);
		cBlue = new Checkbox("Blue", channel, false);
		cGreen = new Checkbox("Green", channel, false);
		cRed = new Checkbox("Red", channel, false);

		interpolation = new CheckboxGroup();
		cLinear = new Checkbox("Linear", interpolation, false);
		cSpline = new Checkbox("Spline", interpolation, true);

		lChannel = new Label("Channel");
		lInterpolation = new Label("Interpolation");
		lMouse = new Label("(--- , ---)", Label.LEFT);
		plot.setLabelMouse(lMouse);
		panel.setLayout(null);

		lChannel.setBounds(275,10,60,10);
		cAll.setBounds(275, 30, 65, 25);
		cRed.setBounds(275, 50, 65, 25);
		cGreen.setBounds(275,70, 65, 25);
		cBlue.setBounds(275, 90, 65, 25);

		lInterpolation.setBounds(343,10,120,10);
		cLinear.setBounds(343, 30, 65, 25);
		cSpline.setBounds(343, 50, 65, 25);
	
		plot.setBounds(10, 10, 255, 255);



		buttonRc.setBounds(290,120,130,30);
		buttonRa.setBounds(290,150,130,30);
		buttonApply.setBounds(290,210,130,30);

		lMouse.setBounds(265,245,75,30);
		
		panel.add(cAll);
		panel.add(cRed);
		panel.add(cGreen);
		panel.add(cBlue);
		panel.add(cLinear);
		panel.add(cSpline);
		panel.add(plot);
		panel.add(lChannel);
		panel.add(lInterpolation);
		panel.add(lMouse);
		panel.add(buttonRc);
		panel.add(buttonRa);
		panel.add(buttonApply);

		add(panel);

		buttonRa.addActionListener(this);
		buttonRc.addActionListener(this);
		buttonApply.addActionListener(this);
		cAll.addItemListener(this);
		cRed.addItemListener(this);
		cGreen.addItemListener(this);
		cBlue.addItemListener(this);
		cLinear.addItemListener(this);
		cSpline.addItemListener(this);
		plot.addMouseMotionListener(this);
		plot.addMouseListener(this);
		channelP[0] = new Channel();
		channelP[1] = new Channel();
		channelP[2] = new Channel();
		channelP[3] = new Channel();
		loadChannel(currentChannel);
	}
	
	public void lutCopy(int[] dst, int[] src){
		for(int i=0;i<256;i++)
          {
            dst[i]=src[i];
          }
		
	}
	
		

	@Override
	public void actionPerformed(ActionEvent e)
    {
        Object source=e.getSource();


		if(source == buttonApply)
        {
			imp.updateAndRepaintWindow();
		   	imp.changes = true;
			//HTML
			String str = "<H1 align = center>Curve</H1>";
			str += "<i>Regola i valori di intenista' dei pixel dell'immagine secondo le curve di colore desiderate.</i>";
			str += "<br><br><b>Dettagli:</b><br><br>";
			str += "'Curve' mappa i valori dell'immagine in ingresso sui valori dell'immagine in uscita secondo la curva di colore impostata: la coordinata x della curva verra' mappata sul valore di y corrispondente.<br><br>";
			str += getValues();
			J2Html report = new J2Html();
			report.changeTextToHtml(str);
		 
       	}
		
		if(source == buttonRa){
			channelP[0] = new Channel();
			channelP[1] = new Channel();
			channelP[2] = new Channel();
			channelP[3] = new Channel();
			loadChannel(currentChannel);
			preview();
		}
		
		if(source == buttonRc){
			if(currentChannel == 0) { channelP[0] = new Channel(); loadChannel(0);}
			if(currentChannel == 1) { channelP[1] = new Channel(); loadChannel(1);}
			if(currentChannel == 2) { channelP[2] = new Channel(); loadChannel(2);}
			if(currentChannel == 3) { channelP[3] = new Channel(); loadChannel(3);}
			preview();
		}

	}

	public int[] loadChannel(int c){
		plot.loadChannel(channelP[c].x,channelP[c].y);
		return plot.findLUT();
	}

private void preview(){
			ImagePlus orig = new Duplicator().run(imp_original);
			imp.setImage(orig);
			int[] lut_r = new int[256];
			int[] lut_g = new int[256];
			int[] lut_b = new int[256]; 
			int[] lut_a =  new int[256];

			lutCopy(lut_a, loadChannel(0));
			lutCopy(lut_r, loadChannel(1));
			lutCopy(lut_g, loadChannel(2));
			lutCopy(lut_b, loadChannel(3));
			loadChannel(currentChannel);

			TransformPC cst = new TransformPC(imp, imp.getTitle(), lut_a, lut_r, lut_g, lut_b);
            time=System.currentTimeMillis();
            ImagePlus processed = null;
            if(type==ImagePlus.GRAY8)  processed = cst.createProcessed8bitImage();                  
	        if(type==ImagePlus.COLOR_256) processed = cst.createProcessed8bitImage();                   
	        if(type==ImagePlus.COLOR_RGB) processed = cst.createProcessedRGBImage();
			imp.setImage(processed);
			imp.updateAndDraw();
		   	imp.changes = false;
	}

		public String getValues(){
			String str = "";

			str += "<b>Channel All:</b> ";
			for(int i = 0; i < channelP[0].x.length; i++) str +="("+channelP[0].x[i]+","+channelP[0].y[i]+"); ";
			str += "<br><i>Punti determinanti la curva di tutti i canali.</i><br><br>";
			
			str += "<b>Channel Red:</b> ";
			for(int i = 0; i < channelP[1].x.length; i++) str +="("+channelP[1].x[i]+","+channelP[1].y[i]+"); ";
			str += "<br><i>Punti determinanti la curva del rosso.</i><br><br>";

			str += "<b>Channel Green:</b> ";
			for(int i = 0; i < channelP[2].x.length; i++) str +="("+channelP[2].x[i]+","+channelP[2].y[i]+"); ";
			str += "<br><i>Punti determinanti la curva del verde.</i><br><br>";

			str += "<b>Channel Blue:</b> ";
			for(int i = 0; i < channelP[3].x.length; i++) str +="("+channelP[3].x[i]+","+channelP[3].y[i]+"); ";
			str += "<br><i>Punti determinanti la curva del blu.</i><br><br>";


			return str;
		}

	@Override
	public void itemStateChanged(ItemEvent e) {
				
		Checkbox selection;
		selection = channel.getSelectedCheckbox();
		if(cAll.getState())
		{
			currentChannel = 0;
			loadChannel(currentChannel);
		}

		if(cRed.getState())
		{
			currentChannel = 1;
			loadChannel(currentChannel);
		}

		if(cGreen.getState())
		{
			currentChannel = 2;
			loadChannel(currentChannel);
		}

		if(cBlue.getState())
		{
			currentChannel = 3;
			loadChannel(currentChannel);
		}
		
		if(cSpline.getState()){
			plot.setSpline();
			preview();
		}
		if(cLinear.getState()){
			plot.setLinear();
			preview();
		}
	}



        


public void mouseDragged(MouseEvent e)
        {
          int mx=e.getX();
          int my=e.getY();
          int[] cartes_coord=plot.coordsConverter(mx,my);
      
          for(int i = 1; i < plot.x.length; i++){
          if(plot.control_m[i] )
          {
             if((cartes_coord[0]<=plot.x[i+1])  && (cartes_coord[0]>=plot.x[i-1])  &&((cartes_coord[0]<=255)&&(cartes_coord[1]<=255)))

            {
		   channelP[currentChannel].x[i] = cartes_coord[0];
		   channelP[currentChannel].y[i] = cartes_coord[1]; 
		   loadChannel(currentChannel);
              plot.findLUT();
            } 
          }
         }

		 plot.labMouse.setText("("+cartes_coord[0]+" , "+cartes_coord[1]+")");
        }


        public void mouseMoved(MouseEvent e)
        {
          int mx=e.getX();
          int my=e.getY();

         for(int i = 0; i < plot.x.length; i++){
          if(plot.control_p[i].contains(mx,my))
          {
            plot.control_m[i]=true;  
          }
          else 
          {
            plot.control_m[i]=false;
          }
         }
	}


      public void mousePressed(MouseEvent e) {}
	public void mouseReleased(MouseEvent e) {
		preview();
	}
	public void mouseExited(MouseEvent e) {}
	public void mouseEntered(MouseEvent e) {}
      public void mouseClicked(MouseEvent e) {
          int mx=e.getX();
          int my=e.getY();
          for(int i = 0; i < plot.x.length; i++){
			if(plot.control_p[i].contains(mx,my)) return;
          }

		int[] cartes_coord= plot.coordsConverter(mx,my);
		channelP[currentChannel].addPoint(cartes_coord[0],cartes_coord[1]);
		channelP[currentChannel].sort();
		loadChannel(currentChannel);
		plot.findLUT();
   }  
    
}


class TransformPC
{
      private ImagePlus imp;
      private ImageProcessor ip;
      private int width;
      private int height;
      private int[] lut;
      private String title;        
      private int[] lut_red, lut_green, lut_blue;

      public TransformPC(ImagePlus image, String t, int[] lut_a, int[] lut_r, int[] lut_g, int[] lut_b) 
      {
		imp=image;
        ip=imp.getProcessor();
        width=ip.getWidth();
        height=ip.getHeight();
		title = t;
	   	lut = lut_a;
	   	lut_red = lut_r;
	   	lut_green = lut_g;
	   	lut_blue = lut_b;
     }
      
      public void setLUT(int[] l)
      {
          for(int i=0;i<256;i++)
          {
            lut[i]=l[i];
          }
      }
      
      public byte[] applyTransform(byte[] pixels)
      {
          byte[] output=new byte[pixels.length];  
        
          for(int i=0;i<pixels.length;i++)
          {
            output[i]=(byte)lut[pixels[i]&0xff];
          }
          return output;          
      }
      
      public int[] applyTransform(int[] pixels)
      {
          int[] output=new int[pixels.length];  
		int p_red, p_green, p_blue;

          for(int i=0;i<pixels.length;i++)
          {
            int c=pixels[i];
		
            p_red=(c&0xff0000)>>16;
            p_green=(c&0x00ff00)>>8;
            p_blue=(c&0x0000ff);

           	p_red=lut_red[p_red&0xff];
           	p_green=lut_green[p_green&0xff];
            p_blue=lut_blue[p_blue&0xff];

            p_red=lut[p_red&0xff];
           	p_green=lut[p_green&0xff];
            p_blue=lut[p_blue&0xff];

            output[i]=((p_red&0xff)<<16)+((p_green&0xff)<<8)+(p_blue&0xff);
          }
          return output;          
      }
      
      public ImagePlus createProcessed8bitImage()
      {
        ImageProcessor processed_ip = ip.crop();
        ImagePlus processed= imp.createImagePlus();
        processed.setProcessor(title, processed_ip);
        byte[] processed_pixels = (byte[])processed_ip.getPixels();
        byte[] output=applyTransform(processed_pixels);
        for (int i=0; i<output.length; i++) 
        {
          processed_pixels[i]=output[i];
        }
        //processed.show();
        return processed;
      }
      
      public void createProcessed8bitImage(ImagePlus img)
      {
        byte[] processed_pixels = (byte[])(img.getProcessor()).getPixels();
        byte[] output=applyTransform(processed_pixels);
        for (int i=0; i<output.length; i++) 
        {
          processed_pixels[i]=output[i];
        }
      }
      
      public ImagePlus createProcessedRGBImage()
      {
        ImageProcessor processed_ip = ip.crop();
        ImagePlus processed= imp.createImagePlus();
        processed.setProcessor(title, processed_ip);
        int[] processed_pixels = (int[])processed_ip.getPixels();
        int[] output= applyTransform(processed_pixels);
        for (int i=0; i<output.length; i++) 
        {
          processed_pixels[i]=output[i];
        }
        return processed;
      }
      
      public void createProcessedRGBImage(ImagePlus img)
      {
        int[] processed_pixels = (int[])(img.getProcessor()).getPixels();
        int[] output= applyTransform(processed_pixels);
        for (int i=0; i<output.length; i++) 
        {
          processed_pixels[i]=output[i];
        }
      }
}



@SuppressWarnings( "unchecked" )
class PlotPC extends Canvas //implements MouseMotionListener, MouseListener
{
	private static final int WIDTH=255, HEIGHT=255;
	private double min = 0;
	private double max = 255;
	public Label labMouse;
	private int[] y_values=new int[256];
	private Rectangle2D rect1, rect2;
	public Rectangle2D[] control_p = new Rectangle2D[10];
	public boolean[] control_m = new boolean[10];
	private boolean isSpline = true;
	private Channel channel = new Channel();
      int[] x = {0,255};
	int[] y = {0,255};
	public PlotPC() 
	{
		setSize(WIDTH, HEIGHT);
		findLUT();
	}
        
        
	public void loadChannel(int[] cx, int[] cy){
		x = cx;
		y = cy;
	}

        
	public void setSpline(){
		isSpline = true;
		findLUT();
	}
	public void setLinear(){
		isSpline = false;
		findLUT();
	}

        
        public void setLabelMouse(Label l)
        {
          labMouse=l;  
        }

        public Dimension getPreferredSize() 
        {
          return new Dimension(WIDTH+1, HEIGHT+1);
        }

	public void update(Graphics g) 
        {
		paint(g);
	}

	public void paint(Graphics g) 
        {
          g.setColor( Color.gray);
          g.fillRect(0, 0, WIDTH, HEIGHT);
          g.drawRect(0, 0, WIDTH, HEIGHT);
          g.setColor( new Color(140,140,140));
	      g.drawLine(128,0,128,255);
	      g.drawLine(64,0,64,255);
	      g.drawLine(192,0,192,255);
	      g.drawLine(0,64,255,64);
	      g.drawLine(0,128,255,128);
	      g.drawLine(0,192,255,192);
          g.setColor( Color.white );
          Vector v=new Vector();
          for(int i=0;i<255;i++)
          {
           int[] first_couple=coordsConverter(i,y_values[i]);
           int[] second_couple=coordsConverter((i+1),y_values[i+1]);
           g.drawLine(first_couple[0], first_couple[1], first_couple[0], first_couple[1]);
           g.drawLine(second_couple[0], second_couple[1], second_couple[0], second_couple[1]);
           approximation(g, second_couple[0], second_couple[1], first_couple[0], first_couple[1],v);
          }



          Graphics2D g2=(Graphics2D)g;
          g2.setColor(Color.white);
          for(int i = 0; i < x.length; i++){
          int[] first_couple=coordsConverter(x[i],y[i]);
          control_p[i]=new Rectangle2D.Double(first_couple[0]-4,first_couple[1]-4,8,8);
          g2.setColor(Color.gray);
          g2.fill(control_p[i]);
          g2.setColor(Color.white);
          g2.draw(control_p[i]);
          }

          g=(Graphics)g2;
          g.setColor(Color.white);
        }
        
        public void approximation(Graphics g, int succ_x, int succ_y, int prev_x, int prev_y, Vector v)
        {
          double hypo=Math.sqrt(Math.pow((prev_x-succ_x),2)+Math.pow((prev_y-succ_y),2));
          if(hypo > 1.5D)
          {
            int middle_x=(prev_x+succ_x)/2;
            int middle_y=(prev_y+succ_y)/2;
            approximation(g, succ_x, succ_y, middle_x, middle_y, v);
            approximation(g, prev_x, prev_y, middle_x, middle_y, v);
            g.drawLine(middle_x, middle_y, middle_x, middle_y);
            v.addElement(new Point(middle_x,middle_y));
          }
        }
        
        public int[] coordsConverter(int x, int y)
        {  
          int[] converted_coord=new int[2];
          converted_coord[0]=x;
          converted_coord[1]=255-y;
          return converted_coord;
        }
        

        
	

 public int[] findLUT()
        {
          int[] y_axis=new int[256];  
          
		if(isSpline)
		 	y_axis =  findYSpline();
		else
			y_axis = findYLinear();

          setYValues(y_axis);
          repaint();
          return y_axis;
     }




public int[] findYLinear(){
	int[] y_axis=new int[256];  

	for(int i = 0; i < x.length-1; i++)
		for(int j = x[i]; j < x[i+1]; j++){
			y_axis[j]=findYCoordRect(j,x[i],y[i],x[i+1],y[i+1]);
	}
          
 	return y_axis;
}


	public int[] findYSpline(){ 
		double[] xx =  getDoubleNumbers(x);
		double[] yy =  getDoubleNumbers(y);
		int n = xx.length-1;
   		double p2[] = new double[n+1];
		SplineC s = new SplineC();
		p2 = s.cubicSpline(xx, yy);
		return s.getPoints(p2, 256, n, xx, yy, 256);
	}
		

        public int findYCoordRect(int x,int x0,int y0,int x1,int y1)
        {
          int y;
          if(y0==y1)y=y1;
          else if(x0==x1)y=y1;
               else
               {
		     y=(int)((((float)(x-x0)/(x1-x0))*(y1-y0))+y0);
               }
          return y;
        }



	public double[] getDoubleNumbers(int[] numbers) {

		if(numbers.length == 2) {

			double[] newNumbers = new double[4];
			newNumbers[0] = numbers[0];
			newNumbers[1] = (Math.abs(numbers[1] - numbers[0])/2)-1;
			newNumbers[2] = (Math.abs(numbers[1] - numbers[0])/2)+1;
			newNumbers[3] = numbers[1];
			return newNumbers;
		}
		int dim =(numbers.length*2-2); 
		double[] newNumbers = new double[dim]; 

		for (int index = 1, j = 1; index < numbers.length-1; index++){
			newNumbers[j] = (double)numbers[index]-1;
			newNumbers[j+1] = (double)numbers[index]+1;
			j +=2;
		}

		newNumbers[dim-1] = (double)numbers[numbers.length-1];
	    
		return newNumbers;
	}
              

public void setYValues(int[] values)
        {
          for(int i=0;i<256;i++)
          {
            y_values[i]=values[i];

          }
        }	

          
}


	class J2Html {
		public void changeTextToHtml(String inputTxtFile){
			String [] temp = inputTxtFile.split(".");
			String s,formName = "testForm";
			try{
				FileWriter htmlFile = new FileWriter("report.htm");
				PrintWriter htmlPrintWriter = new PrintWriter(htmlFile);
				htmlPrintWriter.println("<html>");
				htmlPrintWriter.println("<head>");
				htmlPrintWriter.println("<script>");
				
				htmlPrintWriter.println("</script>");
				htmlPrintWriter.println("</head>");
				htmlPrintWriter.println("<form name ="+formName+" >");
				htmlPrintWriter.println("<body>");
				
				htmlPrintWriter.println(inputTxtFile);
				htmlPrintWriter.println("</body>");
				htmlPrintWriter.println("</form>");
				htmlPrintWriter.println("</html>");
				
				htmlPrintWriter.close();
				
				
			}
			catch(Exception e){e.printStackTrace();}
			
		}
		
	}





class SplineC {
  final static int n = 3;
  final static int m = 255;
  public static void main(String argv[]) throws
    IOException {

 	
  }

	public SplineC(){
	}

  public static int[] getPoints(double[] p2, int m, int n, double[] xi, double[] fi, int np){
	// Find the approximation of the function
	    double h = (xi[n]-xi[0])/m;
	    double x = xi[0];
		int[] y = new int[m];
	    for (int i=1; i<np; ++i) {
	      x += h;

	   // Find the interval that x resides
	      int k = 0;
	      double dx = x-xi[0];
	      while (dx >= 0) { 
	        ++k;
	        dx = x-xi[k];
	      }
	      --k;

	   // Find the value of function f(x)
	      dx = xi[k+1]-xi[k];
	      double alpha = p2[k+1]/(6*dx);
	      double beta = -p2[k]/(6*dx);
	      double gamma = fi[k+1]/dx-dx*p2[k+1]/6;
	      double eta = dx*p2[k]/6 - fi[k]/dx;
	      double f = alpha*(x-xi[k])*(x-xi[k])*(x-xi[k])
	                +beta*(x-xi[k+1])*(x-xi[k+1])*(x-xi[k+1])
	                +gamma*(x-xi[k])+eta*(x-xi[k+1]);
	      //System.out.println(x + " " + f);
		if(f > 255) f = 255;
		if(f < 0 ) f = 0;
		y[i] = (int)f;
	    }
	return y;
  }


// Method to carry out the cubic-spline approximation
// with the second-order derivatives returned.

  public static double[] cubicSpline(double x[],
    double f[]) {
    int n = x.length-1;
    double p[] = new double [n+1];
    double d[] = new double [n-1];
    double b[] = new double [n-1];
    double c[] = new double [n-1];
    double g[] = new double [n];
    double h[] = new double [n];

 // Assign the intervals and function differences
    for (int i=0; i<n; ++i) {
      h[i] = x[i+1]-x[i];
      g[i] = f[i+1]-f[i];
    }

 // Evaluate the coefficient matrix elements
    for (int i=0; i<n-1; ++i) {
      d[i] = 2*(h[i+1]+h[i]);
      b[i] = 6*(g[i+1]/h[i+1]-g[i]/h[i]);
      c[i] = h[i+1];
    }

 // Obtain the second-order derivatives
    g = tridiagonalLinearEq(d, c, c, b);
    for (int i=1; i<n; ++i) p[i] = g[i-1];
    return p;
  }

// Method to solve the tridiagonal linear equation set.

  public static double[] tridiagonalLinearEq(double d[],
    double e[], double c[], double b[]) {
    int m = b.length;
    double w[] = new double[m];
    double y[] = new double[m];
    double z[] = new double[m];
    double v[] = new double[m-1];
    double t[] = new double[m-1];

 // Evaluate the elements in the LU decomposition
    w[0] = d[0];
    v[0]  = c[0];
    t[0]  = e[0]/w[0];
    for (int i=1; i<m-1; ++i) {
      w[i]  = d[i]-v[i-1]*t[i-1];
      v[i]  = c[i];
      t[i]  = e[i]/w[i];
    }
    w[m-1]  = d[m-1]-v[m-2]*t[m-2];

 // Forward substitution to obtain y
    y[0] = b[0]/w[0];
    for (int i=1; i<m; ++i)
      y[i] = (b[i]-v[i-1]*y[i-1])/w[i];

 // Backward substitution to obtain z
    z[m-1] = y[m-1];
    for (int i=m-2; i>=0; --i)
      z[i] = y[i]-t[i]*z[i+1];
     
    return z;
  }
}

class Channel{
	int[] x = {0,255};
	int[] y = {0,255};
	
	public Channel(){
	}
	
	public int[] getX(){
		return x;
	}

	public int[] getY(){
		return y;
	}

	public void sort() {
    		int n = x.length;
    		for (int pass=1; pass < n; pass++) {  
			for (int i=0; i < n-pass; i++) {
            		if (x[i] > x[i+1]) {
					int temp = x[i];  
                			int tempy = y[i];  
                			x[i] = x[i+1];  
                			y[i] = y[i+1]; 
                			x[i+1] = temp;
                			y[i+1] = tempy;
            		}
        		}
    		}
	}

	public void addPoint(int nx, int ny){
		int[] newx = new int[x.length+1];
		int[] newy = new int[x.length+1];

		for(int i = 0; i < x.length-1; i++){
	    		newx[i] = x[i];
	    		newy[i] = y[i];			
		}

		newx[x.length-1] = x[x.length-1];
		newx[x.length] = nx;

		newy[x.length-1] = y[x.length-1];
		newy[x.length] = ny;
		
		x = newx;
		y = newy;

	}	

}

