/*
 * -------------------------------------------------------------------------
 *    $Id: PredatorPrey.java,v 1.9 2004/09/01 18:07:54 estewart Exp $
 * -------------------------------------------------------------------------
 *    Copyright (c) 1999 Visual Numerics Inc. All Rights Reserved.
 *
 *    This software is confidential information which is proprietary to
 *    and a trade secret of Visual Numerics, Inc.  Use, duplication or
 *    disclosure is subject to the terms of an appropriate license
 *    agreement.
 *
 *    VISUAL NUMERICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
 *    SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
 *    BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
 *    FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. VISUAL
 *    NUMERICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 *    AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
 *    ITS DERIVATIVES.
 *--------------------------------------------------------------------------
 */

package com.imsl.demo.javagrande;
import com.imsl.chart.*;
import com.imsl.math.*;
import com.imsl.IMSLException;
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;


public class PredatorPrey extends Applet
implements MouseListener, MouseMotionListener {
    private Chart    chart = null;
    private AxisXY    axis;
    static private final int npoints = 100;
    private double    rabbits[], foxes[];
    private double    point[] = {1,3};
    private double    initialRabbit[] = {1};
    private double    initialFox[] = {3};
    private Data    dataSolved;
    private Data    dataError;
    private int        numberSolved;
    
    private void solve() throws IMSLException {
        OdeRungeKutta.Function f = new OdeRungeKutta.Function() {
            public void f(double t, double y[], double yprime[]) {
                yprime[0] = 2.0*y[0] - 2.0*y[0]*y[1];
                yprime[1] = -y[1] + y[1]*y[0];
            }
        };
        
        OdeRungeKutta q = new OdeRungeKutta(f);
        
        double dt = 10.0/(npoints-1);
        for (int k = 0;  k < npoints;  k++) {
            q.solve(k*dt, (k+1)*dt, point);
            rabbits[k] = point[0];
            foxes[k] = point[1];
        }
        numberSolved++;
    }
    
    public void init() {
        rabbits = new double[npoints];
        foxes = new double[npoints];
        try {
            solve();
        } catch (Exception exception) {
            System.out.println(exception);
            return;
        }
        
        chart = new Chart(this);
        chart.getChartTitle().setTitle(new Text("Predator Prey Problem"));
        axis = new AxisXY(chart);
        axis.setAutoscaleInput(AxisXY.AUTOSCALE_OFF);
        axis.getAxisX().setWindow(0.0, 5.0);
        axis.getAxisY().setWindow(0.0, 5.0);
        axis.getAxisX().getAxisTitle().setTitle("Rabbits");
        axis.getAxisY().getAxisTitle().setTitle("Foxes");
        
        Data data = new Data(axis, rabbits, foxes);
        data.setDataType(Data.DATA_TYPE_LINE|Data.DATA_TYPE_MARKER);
        data.setMarkerType(Data.MARKER_TYPE_FILLED_SQUARE);
        data.setMarkerSize(0.75);
        data.setMarkerColor(Color.blue);
        data.setLineColor(Color.blue);
        
        data = new Data(axis, initialRabbit, initialFox);
        data.setDataType(Data.DATA_TYPE_MARKER);
        data.setMarkerType(Data.MARKER_TYPE_FILLED_CIRCLE);
        data.setMarkerSize(1.5);
        data.setMarkerColor(Color.red);
        
        double px[] = {2.5};
        double py[] = {4.7};
        dataSolved = new Data(axis, px, py);
        dataSolved.setLabelType(Data.LABEL_TYPE_TITLE);
        dataSolved.setTitle("solved 1 ODE");
        dataSolved.setTextColor(Color.green);
        
        double ex[] = {2.5};
        double ey[] = {4.2};
        dataError = new Data(axis, ex, ey);
        dataError.setLabelType(Data.LABEL_TYPE_TITLE);
        //dataError.setTitle("solved 1 ODE");
        dataError.setTextColor(Color.red);
        
        
        addMouseListener(this);
        addMouseMotionListener(this);
    }
    
    
    public void update(Graphics g) {
        chart.update(g);
    }
    
    public void paint(Graphics g) {
        chart.paint(g);
    }
    
    public void mouseMoved(MouseEvent event) {
    }
    
    public void mouseDragged(MouseEvent event) {
        updateInitialPoint(event);
    }
    
    public void mouseClicked(MouseEvent event) {
        updateInitialPoint(event);
    }
    
    private void updateInitialPoint(MouseEvent event) {
        axis.mapDeviceToUser(event.getX(), event.getY(), point);
        initialRabbit[0] = point[0];
        initialFox[0] = point[1];
        try {
            solve();
            dataSolved.setTitle("solved "+(++numberSolved)+" ODEs");
            dataError.setTitle("");
        } catch (IMSLException exception) {
            StringBuffer sb = new StringBuffer(exception.toString());
            int nCharsPerLine = 30;
            for (int k = nCharsPerLine;  k < sb.length();  k += nCharsPerLine) {
                for (int j = 0;  j < nCharsPerLine;  j++) {
                    if (sb.charAt(k-j) == ' ') {
                        sb.setCharAt(k-j, '\n');
                        k -= j;
                        break;
                    }
                }
            }
            dataError.setTitle(sb.toString());
        }
        repaint();
    }
    
    public void mousePressed(MouseEvent event) {
    }
    
    public void mouseReleased(MouseEvent event) {
    }
    
    public void mouseEntered(MouseEvent event) {
    }
    
    public void mouseExited(MouseEvent event) {
    }
    
    
    public static void main(String argv[]) {
        PredatorPrey ex = null;
        
        Frame frame = new Frame();
        ex = new PredatorPrey();
        frame.add(ex);
        ex.init();
        frame.setSize(new Dimension(400,400));
        frame.show();
    }
    
}