import ChaosDemos.*;
import java.awt.*;
import java.util.*;

//********************************************************************
/**                    
* Diagnostics for Odes <br>
* Base class for subclassing
* @version 24 October 1997
* @author Michael Cross
*/
//********************************************************************

public class OdesDiagnostics {
               
/** number of variables (icluding time) */
      int nVariables;
/** math constants */      
      static final double Pi=Math.PI;
      static final double Pi2=2*Pi;      
/* flags */
/**  true if user has chosen range with mouse */
      boolean setAxesRange=false;
/** true if transient is to be run on call to restart() */
      boolean runTrans=false;
      public boolean wrapZ=false;
      public double wrapZValue;  
      public boolean wrapY=false;
      public double wrapYValue;
      public boolean wrapX=false;
      public double wrapXValue;  
      public boolean allowDrag=false;            
/** variable to be plotted on x-axis */
      int plot_x=1;
/** variable to be plotted on y-axis */      
      int plot_y=2;
      
/** number of iterations to eliminate transient   */
      int ntrans=0; 
      
/** number of curves */
      int ncurve=-1;     
/** index of first data curve */
      int ncurve1;
/** index of second data curve */
      int ncurve2; 
/** number of iterations */      
      int iterations=0; 
/** delay in graph update         */
      int delay;                 

/** time step (after reduction by delay) */
      double dt=0.02;
/** input time step */      
      double dtp=0.02;   
/** time in evolution */
      double t=0.;    
/** error estimates from solver */      
      double err,errp;           
                  
/** iterated variable (icluding time) */
      double[] x={0.,0.,0.,0.};
/** starting value of x */
      double[] x0={0.,2.,5.,20.};      
/** equation parameters {a,b,c,d} */      
      double[] parameters;
/** Number of equation parameters */      
      public int nParameters;    
/** function parameter */
      double a;        
/** function parameter */                       
      double b;
/** function parameter */      
      double c;
/** function parameter */      
      double d;
/** transient time */    
      double trans;               
/** Range of plot */
      double xmin=0,xmax=1,ymin=0,ymax=1;
      
      String xTitle;
      String yTitle;      
/** parent class */                                                                                                              
      Odes parent;

//******************************************************************
/**
* @param inParent parent class
* @see Map1D
*/
//******************************************************************
      public OdesDiagnostics(Odes inParent) {
            parent=inParent;  
            nVariables=parent.nVariables;               
      }
      
//********************************************************************
/**
* Updates parameters from the text controls in parent class 
*/ 
//********************************************************************            
      public void updateParameters() {                            
            int i;            
            dtp=parent.parameters.parseTextField(4, dtp, true);
            dt=dtp/((double)delay);
            plot_x=parent.parameters.parseTextField(5, plot_x,0,3);
            plot_y=parent.parameters.parseTextField(6, plot_y,0,3); 
            x[0]=0.;
            for(i=1;i<=3;i++) {
                x0[i]=parent.variables.parseTextField(i-1,x0[i]);
                x[i]=x0[i];
            }
            trans=parent.variables.parseTextField(3,trans);
            ntrans=(int)(trans/dtp);
            if(ntrans>0) runTrans=true;                         
      }      
                
//*********************************************************************
/**
* Restarts
*/
//*********************************************************************      
      public boolean restart() {
            return true;
      }

//*********************************************************************
/**
* Iterates Map equations and updates graph
* @return true if iteration successful
*/
//*********************************************************************      
      public boolean iterate() {                   
            return true;
      }
      
//**********************************************************************
/**
* Sets default values of parameters depending on plot type
*/
//**********************************************************************          
      public void setDefaults() {
      }                 
                      
//**********************************************************************
/**
* Resets x-range to 0 < x < 1
*/
//**********************************************************************            
      public void resetRange() {
            xmin=0.;
            xmax=1.;   
            ymin=0.;
            ymax=1.;
            setAxesRange=false;
      }            

//**********************************************************************
/**
* Action to perform on mouse drag. Default is to set range of axes
* and restart
*/
//**********************************************************************      
      public void respondToDrag(double x1, double x2, double y1, double y2) {
            xmin=x1;
            xmax=x2;
            ymin=y1;
            ymax=y2;
            setAxesRange=true;
            parent.restart();
      }

//**********************************************************************
/**
* Action to perform on mouse click. Default is display coordinates 
* of point
*/
//**********************************************************************      
      public void respondToClick(double x, double y) {
            alertDialog alert = new alertDialog(parent,
                "  Point is ("+(float)x+","+(float)y+")");  
      }       

//**********************************************************************
/**
* Shifts x to 0<x<1
* @param x input value
* @return value shifted to between 0 and shift
*/
//**********************************************************************      
      private double mod(double x, double shift) {
         while (x>shift) {
            x=x-shift;
         }   
         while (x<0.) {
            x=x+shift;
         }
         return x;
      }

//**********************************************************************
/**
* Sets delay for movie iteration
*/
//**********************************************************************      
      public void setDelay(int inDelay) {
            delay=inDelay;
      }
      
      public void setWrap(int i, double wrap) {
            switch(i) {
                  case 1:
                        wrapX=true;
                        wrapXValue=wrap;
                        break;
                  case 2:
                        wrapY=true;
                        wrapYValue=wrap;                  
                        break;      
                  case 3:
                        wrapZ=true;
                        wrapZValue=wrap;                  
                        break;
                  default:
                        break;
            }                                             
      }
      
      boolean eliminateTransient() {
            try {
                      parent.status.setText("Eliminating transient...");
                      for(int i=0;i<ntrans;i++) 
                          t=parent.solver.timeStep(x,t,dtp);                       
            } catch (ArithmeticException e) {
                  alertDialog alert = new alertDialog(parent,"Value has diverged. Try again! ");
                  return false;
            }
            return true;               
      } 

}      
