//======================================================
// Numerical Analysis package in java
// Plot class to plot 2D data
// Dr. Turhan Coban
// EGE University, Engineering School, Mechanical Eng. Div.
// =====================================================
import java.io.*;
//classes used by this class
// PlotShapesSW
// Plot2D
// PLotW


abstract class f_x
{
  //single function single independent variable
  // example f=x*x
  abstract double func(double x);
}

abstract class fi_x
{
  // multifunction single independent variable
  // vector of dependent variables are returned
  // example f[0]=x+sin(x)
  //         f[1]=x*x-x
  // func(x) returns the value of f[0] and f[1]
  // as a two dimensional vector

  abstract double[] func(double x);
}
 
public class Plot
{
  // This class reads plot input variables
  // and sets relations between absolute scale and relative scale plot windows
  public String label=" ";                       // Plot Label
  public String xlabel="x";                      // X axis Label
  public String ylabel="y";                      // Y axis Label
  public String filename;                        // file name
  public double xmin,ymin,xmax,ymax;             // real max,min scale
  public int xabsmin,yabsmin,abswidth,absheight; // absolute max,min scale in Pixel dimension
  public int nmax;                               // max number of data points
  public int ni;                                 // data set number with nmax data                        
  public int nline;                              // max number of data sets
  public double x[][];                           // x data
  public double y[][];                           // y=f(x) data
  public int n[];                                // n : number of data in each line
  public int red[],green[],blue[];               // color code 0-255
  public int xgridon=0;                          // x axis grid line on
  public int ygridon=0;                          // y axis grid line on
  public int plottype[];
  // plottype = 0 continuous line
  // plottype = 1 dashed line
  // plottype = 2
  // plottype = 3 
  // plottype = 10 variable character plot type 
  // plottype = 20 rectangle
  // plottype = 21 filled rectangle
  // plottype = 22 circle
  // plottype = 23 filled circle
  // plottype = 24 triangle
  // plottype = 25 diamond
  // plottype = 26 pentagon
  // plottype = 27 hexagon
  // plottype = 28 filled triangle
  // plottype = 29 filled diamond
  // plottype = 30 filled pentagon
  // plottype = 31 filled hexagon
  // plottype = 32 tri sided star
  // plottype = 33 four sided  star
  // plottype = 34 five sided star
  // plottype = 35 six sided star
  // plottype = 36 filled tri sided  star
  // plottype = 37 filled four sided star
  // plottype = 38 filled five sided star
  // plottype = 39 filled six sided star
  // plottype = 40 bar plot
  // plottype = 41 filled bar plot 
  public char ch[];    // plot character (used with plottype 10)
  public int xntic=10;    // number of tics in x axis
  public int yntic=10;    // number of tics in y axis
  BufferedReader fini;
  BufferedReader ffile;
  File plotFile;
  File lineDataFile;
  String fn[];
//constructors
//1.  public Plot() throws IOException : read data from Plot.txt (actual datafiles are listed in Plot.txt)
//2.  public Plot(String pl,String xl,String yl,int xnt,int ynt
//    ,int xgo,int ygo,String fn[],int ipt[],int ir[],int ig[]
//    ,int ib[]) throws IOException  : read data file names from String fn[]
//3.  public Plot(String fn[],int ipt[],int ir[],int ig[],int ib[]) throws IOException
//                                  : read data file names from String fn[]
//4.  public Plot(String fn[]) throws IOException  : read data file names from String fn[]
//5.  public Plot(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[]) 
//                                  : read data from xi yi arrays
//6.  public Plot(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib)
//                                  : read data from a simple function f_x f  f(x)
//7.  public Plot(f_x f,double xm,double xma,int N) : read data from a simple function f_x f  f(x)
//8.  public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function,
//   int ipt[],int ir[],int ig[],int ib[]) : : read data from a series of functions fi_x f  fi(x)
//
//
	//read input variables from Plot.txt
    //adding max-min prompts and input fields
    //initial values of max and mins
    // Structure of input file
    // filename
    // xlabel
    // ylabel
    // nline 
    // datafilename plottype redcolor greencolor bluecolor
    // ........
    // datafilename plottype redcolor greencolor bluecolor
    //
    // A sample data file input :
    // filename
    // xaxislabel
    // yaxislabel
    // 4 
    // b.dat 22 0 0 0
    // a.dat 21 0 255 0
    // a.dat 0 0 255 0
    // b.dat 0 0 0 255
    //
    // see above for meaning of plot types
/*
  public Plot()
  {
  double xi[]=new double[1];
  double yi[]=new double[1];
  xi[0]=0.0;
  yi[0]=0.0;
  pp1(xi,yi);
  }
*/
    
public Plot() throws IOException 
{
    xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    try{
       fini=new BufferedReader(new FileReader("Plot.txt"));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
    label=Text.readStringLine(fini);
    xlabel=Text.readStringLine(fini);
    ylabel=Text.readStringLine(fini);
    nline=Text.readInt(fini);
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    //read all data to determine limit values
    String fn[];
    fn=new String[nline];
    int i,j;
    for(i=0;i<nline;i++)
    {
       fn[i]=Text.readString(fini);
       plottype[i]=Text.readInt(fini);
       if((plottype[i] >= 10)&&(plottype[i] <= 19)) ch[i]=Text.readChar(fini);
       red[i]=Text.readInt(fini);
       green[i]=Text.readInt(fini);
       blue[i]=Text.readInt(fini);
       j=0;
       n[i]=0;
       //open ffile             
           try{
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       try{
       while(ffile!=null)
       {
       xtemp=Text.readDouble(ffile);
       ytemp=Text.readDouble(ffile);
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }
          } catch(EOFException e_eof)
          {
          //close ffile
          try{
          ffile.close();
             } catch(IOException e)
             {
             System.err.println("Error Closing File\n"+e.toString());
             System.exit(1);
             }
          } //End of EOFException

       if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
    }
//close ffile
    try{
       ffile.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }
    x=new double[nline][nmax];
    y=new double[nline][nmax];
    //re-read the data again to load it
    for(i=0;i<nline;i++)
    {
       //open ffile
           try{      
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       for(j=0;j<n[i];j++)
       {
          x[i][j]=Text.readDouble(ffile);
          y[i][j]=Text.readDouble(ffile);

       }
    //close ffile
    try{
       ffile.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }
    }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
//close fini
    try{
       fini.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }
  }
  
   
  public Plot(String pl,String xl,String yl,int xnt,int ynt
  ,int xgo,int ygo,String fn[],int ipt[],int ir[],int ig[]
  ,int ib[]) throws IOException
   { 
    xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    setXtic(10);
    setYtic(10);
    setGrid(0,0);
    double xtemp,ytemp;       
    setPlabel(pl);
    setXlabel(xl);
    setYlabel(yl);
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    //read all data to determine limit values
    int i,j;
    nline=fn.length;
    for(i=0;i<nline;i++)
    {
       plottype[i]=ipt[i];
       if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';
       red[i]=ir[i];
       green[i]=ig[i];
       blue[i]=ib[i];
       j=0;
       n[i]=0;
       //open ffile  
       System.out.println("isim ="+fn[i]);           
           try{
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       try{
       while(ffile!=null)
       {
       xtemp=Text.readDouble(ffile);
       ytemp=Text.readDouble(ffile);
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }
          } catch(EOFException e_eof)
          {
          //close ffile
          try{
          ffile.close();
             } catch(IOException e)
             {
             System.err.println("Error Closing File\n"+e.toString());
             System.exit(1);
             }
          } //End of EOFException

        if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
    }
    System.out.println("nline = "+nline+"nmax="+nmax);
    x=new double[nline][nmax];
    y=new double[nline][nmax];
    //re-read the data again to load it
    for(i=0;i<nline;i++)
    {
       //open ffile
           try{      
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       for(j=0;j<n[i];j++)
       {
          x[i][j]=Text.readDouble(ffile);
          y[i][j]=Text.readDouble(ffile);
       }
    //close ffile
    try{
       ffile.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }

    }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }
   
   public Plot(String fn[],int ipt[],int ir[],int ig[],int ib[]) throws IOException
   { 
    // reading data from file and initilisation
	xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    //read all data to determine limit values
    int i,j;
    nline=fn.length;
    for(i=0;i<nline;i++)
    {
       plottype[i]=ipt[i];
       if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';
       red[i]=ir[i];
       green[i]=ig[i];
       blue[i]=ib[i];
       j=0;
       n[i]=0;
       //open ffile  
       System.out.println("isim ="+fn[i]);           
           try{
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       try{
       while(ffile!=null)
       {
       xtemp=Text.readDouble(ffile);
       ytemp=Text.readDouble(ffile);
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }
          } catch(EOFException e_eof)
          {
          //close ffile
          try{
          ffile.close();
             } catch(IOException e)
             {
             System.err.println("Error Closing File\n"+e.toString());
             System.exit(1);
             }
          } //End of EOFException

        if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
    }
    x=new double[nline][nmax];
    y=new double[nline][nmax];
    //re-read the data again to load it
    for(i=0;i<nline;i++)
    {
       //open ffile
           try{      
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       for(j=0;j<n[i];j++)
       {
          x[i][j]=Text.readDouble(ffile);
          y[i][j]=Text.readDouble(ffile);
       }
    //close ffile
    try{
       ffile.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }
    }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }
  

	
  public Plot(String fn[]) throws IOException
   {
   //reading data from file(s)	   
   nline=fn.length;
   int ipt[]=new int[nline];
   int ir[]=new int[nline];
   int ig[]=new int[nline];
   int ib[]=new int[nline];	   
	xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    //read all data to determine limit values
    int i,j;
    nline=fn.length;
    for(i=0;i<nline;i++)
    {
       plottype[i]=ipt[i];
       if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';
       red[i]=ir[i];
       green[i]=ig[i];
       blue[i]=ib[i];
       j=0;
       n[i]=0;
       //open ffile  
       System.out.println("isim ="+fn[i]);           
           try{
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       try{
       while(ffile!=null)
       {
       xtemp=Text.readDouble(ffile);
       ytemp=Text.readDouble(ffile);
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }
          } catch(EOFException e_eof)
          {
          //close ffile
          try{
          ffile.close();
             } catch(IOException e)
             {
             System.err.println("Error Closing File\n"+e.toString());
             System.exit(1);
             }
          } //End of EOFException

        if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
    }
    x=new double[nline][nmax];
    y=new double[nline][nmax];
    //re-read the data again to load it
    for(i=0;i<nline;i++)
    {
       //open ffile
           try{      
       ffile=new BufferedReader(new FileReader(fn[i]));
       } catch(IOException e)
       {
       System.err.println("Error Opening File \n"+e.toString());
       System.exit(1);
       }
       for(j=0;j<n[i];j++)
       {
          x[i][j]=Text.readDouble(ffile);
          y[i][j]=Text.readDouble(ffile);
       }
    //close ffile
    try{
       ffile.close();
       } catch(IOException e)
       {
       System.err.println("Error Closing File\n"+e.toString());
       System.exit(1);
       }
    }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
   }  
   
  public Plot(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[])
  { 
    pp2(xi,yi,ipt,ir,ig,ib);
  }
  
  public void pp2(double xi[][],double yi[][])
  {
  int ir[];
  int ig[];
  int ib[];
  int ipt[];
  int nn=xi.length;
  ir=new int[nn];
  ig=new int[nn];
  ib=new int[nn];
  ipt=new int[nn];
  for(int i=0;i<nn;i++)
  {
    ir[i]=0;
    ig[i]=0;
    ib[i]=0;
    ipt[i]=0;
  }     
  pp2(xi,yi,ipt,ir,ig,ib);	  
  }
    
  public void pp2(double xi[][],double yi[][],int ipt[])
  {
  int ir[];
  int ig[];
  int ib[];
  int nn=xi.length;
  ir=new int[nn];
  ig=new int[nn];
  ib=new int[nn];
  for(int i=0;i<nn;i++)
  {
    ir[i]=0;
    ig[i]=0;
    ib[i]=0;
  }     
  pp2(xi,yi,ipt,ir,ig,ib);	  
  }
  
  public void pp2(double xi[][],double yi[][],int ipt[],int ir[],int ig[],int ib[])
   { 
    // reading data from initial array
	xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];  
    ch=new char[100];
    //read all data to determine limit values
    int i,j;
    nline=xi.length;
    for(i=0;i<nline;i++)
    {
       plottype[i]=ipt[i];
       if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';
       red[i]=ir[i];
       green[i]=ig[i];
       blue[i]=ib[i];
       nline=xi.length;
       n[i]=0;
       for(j=0;j<xi[i].length;j++)
       {
       xtemp=xi[i][j];
       ytemp=yi[i][j];
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }       
       if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
       } //end of for
       x=new double[nline][nmax];
       y=new double[nline][nmax];
       for(i=0;i<nline;i++)
       {
          for(j=0;j<n[i];j++)
          {
          x[i][j]=xi[i][j];
          y[i][j]=yi[i][j];
          }
       }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }
  
  public Plot(double xiyi[][])
  {
  double xi[];
  double yi[];
  int n=xiyi[0].length;
  xi=new double[n];
  yi=new double[n];
  for(int i=0;i<n;i++)
  {
  xi[i]=xiyi[0][i];
  yi[i]=xiyi[1][i];
  }
  pp1(xi,yi);
  }
 
      
  public Plot(double xi[][],double yi[][])
  { 
  pp2(xi,yi);
  }
  
  public void pp1( double xi[],double yi[])
  {
  pp1(xi,yi,0,0,0,0);
  }
    
  public void pp1( double xi[],double yi[],int ipt)
  {
  pp1(xi,yi,ipt,0,0,0);
  }
    
  public void pp1( double xi[],double yi[],int ipt,int ir,int ig,int ib)
  {
    // reading data from initial array
	xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100]; 
    ch=new char[100];
    //read all data to determine limit values
    int i,j;
    nline=1;
    plottype[0]=ipt;
    red[0]=ir;
    green[0]=ig;
    blue[0]=ib;
    nline=1;
    n[0]=0;
       plottype[0]=ipt;
       if(plottype[0] == 10) ch[0]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[0] == 11) ch[0]='#';
       if(plottype[0] == 12) ch[0]='$';
       if(plottype[0] == 13) ch[0]='%';
       if(plottype[0] == 14) ch[0]='&';
       if(plottype[0] == 15) ch[0]='£';
       if(plottype[0] == 16) ch[0]='~';
       if(plottype[0] == 17) ch[0]='+';
       if(plottype[0] == 18) ch[0]='^';
       if(plottype[0] == 19) ch[0]='=';
       for(j=0;j<xi.length;j++)
       {
       xtemp=xi[j];
       ytemp=yi[j];
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[0]++;
       }       
       nmax=n[0];ni=0;
       x=new double[nline][nmax];
       y=new double[nline][nmax];
       i=0;
          for(j=0;j<n[0];j++)
          {
          x[i][j]=xi[j];
          y[i][j]=yi[j];
          }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }   
  
  public Plot(double xi[],double yi[])
   { 
    pp1(xi,yi);
  }
  
   public Plot(f_x f,double xm,double xma,int N,int ipt,int ir,int ig,int ib)
   { 
    // reading data from a given function//one data set only
	xmin=xm;
    xmax=xma;
    nmax=N;
    ni=0;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    double xi[]=new double[N];
    double yi[]=new double[N];
    double dx=(xmax-xmin)/N;
    double xx=xmin;
    for(int j=0;j<N;j++)
    {  
	  xi[j]=xx;
	  yi[j]=f.func(xx);
	xx+=dx;
    }
    pp1(xi,yi);
    //read all data to determine limit values
    int i,j;
    nline=1;
       plottype[0]=ipt;
       if(plottype[0] == 10) ch[0]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[0] == 11) ch[0]='#';
       if(plottype[0] == 12) ch[0]='$';
       if(plottype[0] == 13) ch[0]='%';
       if(plottype[0] == 14) ch[0]='&';
       if(plottype[0] == 15) ch[0]='£';
       if(plottype[0] == 16) ch[0]='~';
       if(plottype[0] == 17) ch[0]='+';
       if(plottype[0] == 18) ch[0]='^';
       if(plottype[0] == 19) ch[0]='=';
       red[0]=ir;
       green[0]=ig;
       blue[0]=ib;
       nline=1;
       n[0]=0;
       for(j=0;j<xi.length;j++)
       {
       xtemp=xi[j];
       ytemp=yi[j];
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[0]++;
       }       
       nmax=n[0];ni=0;
       x=new double[1][nmax];
       y=new double[1][nmax];
          for(j=0;j<n[0];j++)
          {
          x[0][j]=xi[j];
          y[0][j]=yi[j];
          }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }
  
  public Plot(f_x f,double xm,double xma,int N)
   { 
    // reading data from a given function//one data set only
	int ipt=0;
	int ir=0;
	int ig=0;
	int ib=0;
    xmin=xm;
    xmax=xma;
    nmax=N;
    ni=0;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    double xi[]=new double[N];
    double yi[]=new double[N];
    double dx=(xmax-xmin)/N;
    double xx=xmin;
    for(int j=0;j<N;j++)
    {  
	  xi[j]=xx;
	  yi[j]=f.func(xx);
	xx+=dx;
    }
    //read all data to determine limit values
    int i,j;
    nline=1;
       plottype[0]=ipt;
       if(plottype[0] == 10) ch[0]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[0] == 11) ch[0]='#';
       if(plottype[0] == 12) ch[0]='$';
       if(plottype[0] == 13) ch[0]='%';
       if(plottype[0] == 14) ch[0]='&';
       if(plottype[0] == 15) ch[0]='£';
       if(plottype[0] == 16) ch[0]='~';
       if(plottype[0] == 17) ch[0]='+';
       if(plottype[0] == 18) ch[0]='^';
       if(plottype[0] == 19) ch[0]='=';
       red[0]=ir;
       green[0]=ig;
       blue[0]=ib;
       nline=1;
       n[0]=0;
       for(j=0;j<xi.length;j++)
       {
       xtemp=xi[j];
       ytemp=yi[j];
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[0]++;
       }       
       nmax=n[0];ni=0;
       x=new double[1][nmax];
       y=new double[1][nmax];
          for(j=0;j<n[0];j++)
          {
          x[0][j]=xi[j];
          y[0][j]=yi[j];
          }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  }
  
  public Plot(fi_x f,double xm,double xma,int Number_of_Data,int Number_of_Function)
   { 
    // reading data from a given functon set
    // same xmin xmax and Number_of_data for each function
   nline=Number_of_Function;
   int ipt[]=new int[nline];
   int ir[]=new int[nline];
   int ig[]=new int[nline];
   int ib[]=new int[nline];	   
	xmin=xm;
    xmax=xma;
    ymin=9.99e50;
    ymax=-9.99e50;
    double xtemp,ytemp;       
    n=new int[100];
    red=new int[100];
    green=new int[100];
    blue=new int[100];
    plottype=new int[100];
    ch=new char[100];
    int N=Number_of_Data;
    double dx=(xmax-xmin)/N;
    double xx=xmin;
    int NF=Number_of_Function;
    nline=NF;
    double xi[][]=new double[NF][N];
    double yi[][]=new double[NF][N];
    double yy[]=new double[NF];
    for(int j=0;j<N;j++)
    {  
	  yy=f.func(xx);
	  for(int i=0;i<NF;i++)
	    {  yi[i][j]=yy[i];
	       xi[i][j]=xx;}
	  xx+=dx;
    }
    
    //read all data to determine limit values    
    for(int i=0;i<nline;i++)
    {
       plottype[i]=ipt[i];
       if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';red[i]=ir[i];
       green[i]=ig[i];
       blue[i]=ib[i];
       nline=xi.length;
       n[i]=0;
       for(int j=0;j<N;j++)
       {
       xtemp=xi[i][j];
       ytemp=yi[i][j];
       if(xtemp<xmin) xmin=xtemp;
       if(xtemp>xmax) xmax=xtemp;
       if(ytemp<ymin) ymin=ytemp;
       if(ytemp>ymax) ymax=ytemp;
       n[i]++;
       }       
       if(i==0) {nmax=n[i];ni=i;}
       else
         {
         if(n[i]>nmax) {nmax=n[i];ni=i;}
         }
       } //end of for
       
       
       x=new double[nline][nmax];
       y=new double[nline][nmax];
       for(int i=0;i<nline;i++)
       {
          for(int j=0;j<n[i];j++)
          {
          x[i][j]=xi[i][j];
          y[i][j]=yi[i][j];
          }
       }
    set_plotwindow(500,500,0.1,0.1,0.9,0.9);
  } 
  
  
  public void setPlabel(String ip) {label=ip;}
  public void setXlabel(String ix) {xlabel=ix;}
  public void setYlabel(String iy) {ylabel=iy;}
  public void setXYlabel(String ix,String iy) {xlabel=ix;ylabel=iy;}
  
  public void set_plotwindow(int width,int height,double xip,double yip,double dxp,double dyp)
  {
    //sets rectangular plot window    
    //function scale input variables :
    //real scale plot window width
    //real scale plot window height
    //xip: minimum real scale x
    //yip : minimum real scale y
    //dxp: real scale x width  xmax=xip+dxp
    //dyp: real scale y height ymax=yip+dyp

    // xabsmin : absolute (pixel) scale minimum x
    // yabsmin : absolute (pixel) scale minimum y
    //abswidth : absolute (pixel) scale x width (maximum x=minimum x+abswidth)
    //absheight: absolute (pixel) scale y height (maximum y=minimum y+absheight)
    
    xabsmin   =  (int)(width*(xip+0.2));
    yabsmin   =  (int)(height*(yip+0.2));
    abswidth  =  (int)(width*dxp);
    absheight =  (int)(height*dyp);
  }
  
 public void setabsMaxMin(int ixmin,int iymin,int idx,int idy)
 {
 xabsmin=ixmin;
 yabsmin=iymin;
 abswidth=idx;
 absheight=idy;
 }


 
 public void addData(double xi[],double yi[])
 {
 addData(xi,yi,0,0,0,0);
 }
 
 public void addData(double xi[],double yi[],int iplottype)
 {
 addData(xi,yi,iplottype,0,0,0);
 }
 
 public void addData(double xi[],double yi[],int iplottype,int ir,int ig,int ib)
 {
       int oldnmax=nmax;
       int oldnline=nline;
       nline+=1;
	   n[oldnline]=xi.length;
	   plottype[nline-1]=iplottype;
	   if(plottype[nline-1] == 10) ch[nline-1]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[nline-1] == 11) ch[nline-1]='#';
       if(plottype[nline-1] == 12) ch[nline-1]='$';
       if(plottype[nline-1] == 13) ch[nline-1]='%';
       if(plottype[nline-1] == 14) ch[nline-1]='&';
       if(plottype[nline-1] == 15) ch[nline-1]='£';
       if(plottype[nline-1] == 16) ch[nline-1]='~';
       if(plottype[nline-1] == 17) ch[nline-1]='+';
       if(plottype[nline-1] == 18) ch[nline-1]='^';
       if(plottype[nline-1] == 19) ch[nline-1]='=';
	   red[nline-1]=ir;
	   green[nline-1]=ig;
	   blue[nline-1]=ib;
	   if(xi.length>nmax)
       {
       nmax=xi.length;
       ni=nline;
	   }
	   double xa[][]=new double[nline][nmax];
	   double ya[][]=new double[nline][nmax];
       for(int i=0;i<oldnline;i++)
       {       
	      for(int j=0;j<n[i];j++)
          {
          xa[i][j]=x[i][j];
          ya[i][j]=y[i][j];
          }
      }
      for(int j=0;j<n[nline-1];j++)
          {
          xa[nline-1][j]=xi[j];
          ya[nline-1][j]=yi[j];
          }
      x=xa;
      y=ya;       
      setMinMax();
}

public void addData(double xi[][],double yi[][])
{
int ip[]=new int[0];
int ir[]=new int[0];
int ig[]=new int[0];
int ib[]=new int[0];
addData(xi,yi,ip,ir,ig,ib);
}

public void addData(double xi[][],double yi[][],int ip[])
{
int ir[]=new int[0];
int ig[]=new int[0];
int ib[]=new int[0];
addData(xi,yi,ip,ir,ig,ib);
}

public void addData(double xi[][],double yi[][],int ip[],int ir[],int ig[],int ib[])
 {
       int oldnmax=nmax;
       int oldnline=nline;
       nline+=xi.length;
	   for(int i=oldnline;i<nline;i++)
	   {
	   plottype[i]=ip[i-oldnline];
	   if(plottype[i] == 10) ch[i]='*';//you can change character set by using setPlotType(0,'%');
       if(plottype[i] == 11) ch[i]='#';
       if(plottype[i] == 12) ch[i]='$';
       if(plottype[i] == 13) ch[i]='%';
       if(plottype[i] == 14) ch[i]='&';
       if(plottype[i] == 15) ch[i]='£';
       if(plottype[i] == 16) ch[i]='~';
       if(plottype[i] == 17) ch[i]='+';
       if(plottype[i] == 18) ch[i]='^';
       if(plottype[i] == 19) ch[i]='=';
	   red[i]=ir[i-oldnline];
	   green[i]=ig[i-oldnline];
	   blue[i]=ib[i-oldnline];
	   n[i]=xi[i-oldnline].length;
	   if(xi[i-oldnline].length>nmax)
       {
       nmax=xi[i-oldnline].length;
       ni=i;
	   }
       }
	   double xa[][]=new double[nline][nmax];
	   double ya[][]=new double[nline][nmax];
       for(int i=0;i<oldnline;i++)
       {       
	      for(int j=0;j<n[i];j++)
          {
          xa[i][j]=x[i][j];
          ya[i][j]=y[i][j];
          }
      }
      int k=0;
      for(int i=oldnline;i<nline;i++)
      {     
      for(int j=0;j<n[i];j++)
          {
          xa[i][j]=xi[i-oldnline][j];
          ya[i][j]=yi[i-oldnline][j];          
          }
      }   
      x=xa;
      y=ya;       
      setMinMax();
}

public void addFunction(f_x f,double xmi,double xma,int N,int ipt)
{
addFunction(f,xmi,xma,N,ipt,0,0,0);	
}

public void addFunction(f_x f,double xmi,double xma,int N)
{
addFunction(f,xmi,xma,N,0);	
}

public void addFunction(f_x f,double xmi,double xma,int N,int ipt,int ir,int ig,int ib)	
{
double xi[]=new double[N];
double yi[]=new double[N];
double dx=(xma-xmi)/N;
double xx=xmi;
for(int j=0;j<N;j++)
{  
	xi[j]=xx;
	yi[j]=f.func(xx);
	xx+=dx;
}
addData(xi,yi,ipt,ir,ig,ib);
}

public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function)
{
int ipt[]=new int[Number_of_Function];
int ir[]=new int[Number_of_Function];
int ig[]=new int[Number_of_Function];
int ib[]=new int[Number_of_Function];
addFunction(f,xmin,xmax,Number_of_Data,Number_of_Function,ipt,ir,ig,ib);
}   

public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function,int ipt[])
{
int ir[]=new int[Number_of_Function];
int ig[]=new int[Number_of_Function];
int ib[]=new int[Number_of_Function];
addFunction(f,xmin,xmax,Number_of_Data,Number_of_Function,ipt,ir,ig,ib);
} 

public void addFunction(fi_x f,double xmin,double xmax,int Number_of_Data,int Number_of_Function,
   int ipt[],int ir[],int ig[],int ib[])	
{
    int N=Number_of_Data;
    double dx=(xmax-xmin)/N;
    double xx=xmin;
    int NF=Number_of_Function;
    double xi[][]=new double[NF][N];
    double yi[][]=new double[NF][N];
    double yy[]=new double[NF];
    for(int j=0;j<N;j++)
    {  
	  yy=f.func(xx);
	  for(int i=0;i<NF;i++)
	    {  yi[i][j]=yy[i];
	       xi[i][j]=xx;}
	  xx+=dx;
    }
addData(xi,yi,ipt,ir,ig,ib);
}

public void setPlotType(int plot_type[])
{
for(int i=0;i<plot_type.length;i++)
  {
  setPlotType(i,plot_type[i]);
  }
setMinMax();
}
	
public void setPlotType(int dataset,int plot_no)
{
  // plottype = 0 continuous line
  // plottype = 1 dashed line
  // plottype = 2
  // plottype = 3 
  // plottype = 10 variable character plot type 
  // plottype = 20 rectangle
  // plottype = 21 filled rectangle
  // plottype = 22 circle
  // plottype = 23 filled circle
  // plottype = 24 triangle
  // plottype = 25 diamond
  // plottype = 26 pentagon
  // plottype = 27 hexagon
  // plottype = 28 filled triangle
  // plottype = 29 filled diamond
  // plottype = 30 filled pentagon
  // plottype = 31 filled hexagon
  // plottype = 32 triangle star
  // plottype = 33 diamond star
  // plottype = 34 pentagon star
  // plottype = 35 hexagon star
  // plottype = 36 filled triangle star
  // plottype = 37 filled diamond star
  // plottype = 38 filled pentagon star
  // plottype = 39 filled hexagon star
  // plottype = 40 bar plot
  // plottype = 41 filled bar plot 
  plottype[dataset]=plot_no;
  if(plot_no==10) ch[dataset]='*';   //user defined char is defined as * 
}

public void setPlotType(int dataset,char plot_char)
{ 
  // plottype = 10 user defined character plot
  plottype[dataset]=10;
  ch[dataset]=plot_char;    
}


public void setXgrid(int igx)
{
  xgridon=igx;
}
public void setYgrid(int igy)
{
  ygridon=igy;
}
public void setGrid(int igx,int igy)
{
 xgridon=igx;
 ygridon=igy;
}
public void setXtic(int ixt)
{
  xntic=ixt;
}
public void setYtic(int iyt)
{
  yntic=iyt;
}
public void setXYtic(int ixt,int iyt)
{
    xntic=ixt;
	yntic=iyt;
}

public void setColor(int dataset,int ired,int igreen,int iblue)
{
 red[dataset]=ired;
 green[dataset]=igreen;
 blue[dataset]=iblue;
}

public void setColor(int ired[],int igreen[],int iblue[])
{
  for(int i=0;i<nline;i++)
  {	
   red[i]=ired[i];
   green[i]=igreen[i];
   blue[i]=iblue[i];
  }
}
public void setMinMax()
{   
	xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    for(int i=0;i<nline;i++)
       {       
	      for(int j=0;j<n[i];j++)
          {
          if(x[i][j]>xmax) xmax=x[i][j];
          if(x[i][j]<xmin) xmin=x[i][j];
          if(y[i][j]>ymax) ymax=y[i][j];
          if(y[i][j]<ymin) ymin=y[i][j];
          }
      }
}
public void setMinMax(double xi[][],double yi[][])
{
    xmin=9.99e50;
    xmax=-9.99e50;
    ymin=9.99e50;
    ymax=-9.99e50;
    for(int i=0;i<nline;i++)
          { 
	      if(xi[i].length>nmax) {nmax=xi[i].length;ni=i;}	      
	      for(int j=0;j<xi[i].length;j++)
          {
          if(xi[i][j]>xmax) xmax=xi[i][j];
          if(xi[i][j]<xmin) xmin=xi[i][j];
          if(yi[i][j]>ymax) ymax=yi[i][j];
          if(yi[i][j]<ymin) ymin=yi[i][j];
          }          
      }
}
public void setMinMax(double iminx,double imaxx,double iminy,double imaxy)
{
xmin=iminx;
ymin=iminy;
xmax=imaxx;
ymax=imaxy;
}

public void plot()
{
PlotW.plot(this);
}


}