package iDSS.gridDisp;

import javax.swing.*;
//import javax.swing.border.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.*;


import iDSS.*;
import iDSS.grids.*;
import iDSS.disp.*;
import iDSS.utils.*;
import iDSS.xyGraph.*;



public class DrawingPanel2 extends JPanel implements MouseListener, MouseMotionListener,
                        ComponentListener {

  private boolean firstTime = true;

  private BufferedImage bufferImage;
  private int leftMargin,rightMargin,topMargin,bottomMargin,sizeX,sizeY;

  private int x1, x2, y1, y2;
  private String mouseCoords;

  private GraphicalDisplay2 parentFrame;


  public DrawingPanel2 (int width,int height) {

    System.out.println("In Constructor of DrawingPanel2");

    leftMargin = 0;
    rightMargin = 0;
    topMargin = 0;
    bottomMargin = 0;

    sizeX = width;
    sizeY = height;

    parentFrame = null;

    bufferImage = new BufferedImage (sizeX,sizeY,BufferedImage.TYPE_INT_RGB);

    if (bufferImage != null) {
      System.out.println("bufferImage created in Drawingpanel2");
      Graphics bg = bufferImage.getGraphics();
      bg.setColor(Color.white);
      bg.fillRect(leftMargin,topMargin,(sizeX-leftMargin-rightMargin),(sizeY-topMargin-bottomMargin));
      bg.setColor(Color.black);

    }


    setSize(new Dimension(sizeX,sizeY));
    setPreferredSize(new Dimension(sizeX,sizeY));
    setVisible(true);

    addMouseListener(this);
    addMouseMotionListener(this);
    addComponentListener(this);


    repaint();
    //setBackground (Color.white);

    System.out.println("Creating DrawingPanel2, width, height : " + width + ", " + height);
    System.out.println("Created size: width, height : " + getWidth() + ", " + getHeight());


  }//public GraphicalDisplay(int cancasX,int canvasY)




  public DrawingPanel2 (int width,int height, GraphicalDisplay2 aParent) {

    System.out.println("In Constructor");

    leftMargin = 0;
    rightMargin = 0;
    topMargin = 0;
    bottomMargin = 0;

    sizeX = width;
    sizeY = height;

    parentFrame = aParent;

    System.out.println("Creating DrawingPanel2, width, height : " + width + ", " + height);

    bufferImage = new BufferedImage (sizeX,sizeY,BufferedImage.TYPE_INT_RGB);

    if (bufferImage != null) {
      System.out.println("bufferImage created");
      Graphics bg = bufferImage.getGraphics();
      bg.setColor(Color.white);
      bg.fillRect(leftMargin,topMargin,(sizeX-leftMargin-rightMargin),(sizeY-topMargin-bottomMargin));
      bg.setColor(Color.black);

    }


    setSize(sizeX,sizeY);
    setVisible(true);

    addMouseListener(this);
    addMouseMotionListener(this);
    addComponentListener(this);


    repaint();
    //setBackground (Color.white);

  }//public GraphicalDisplay(int cancasX,int canvasY)













    public int getCanvasX() {

        return sizeX;

    }//public int getCanvasX()






    public int getCanvasY() {

        return sizeY;

    }//public int getCanvasY()






  public void paint (Graphics g) {


    //System.out.println("In Paint()");


    if (firstTime) {

      firstTime = false;
      System.out.println("firstTime");

      if (bufferImage == null) {
          bufferImage = new BufferedImage(getWidth(),getHeight(),BufferedImage.TYPE_INT_RGB);
          Graphics bg = bufferImage.getGraphics();
          bg.setColor(Color.white);
          bg.fillRect(leftMargin,topMargin,(sizeX-leftMargin-rightMargin),(sizeY-topMargin-bottomMargin));
          bg.setColor(Color.black);
      }



    }

    g.drawImage (bufferImage,0,0,this);



  } //public void paint (Graphics g)






  public void setupPanel() {

      System.out.println("In setupPanel()");

      while(bufferImage.getGraphics() == null)
        repaint();

      Graphics g = bufferImage.getGraphics();

      int sizeX = getWidth();
      int sizeY = getHeight();
      //repaint();


  }//public void setupPanel ()




    public BufferedImage getCanvas() {


/*
        while(firstTime) {
            System.out.println("Drawingpanel2:getCanvas(), still firstTime");
            repaint();
        }

*/
        System.out.println("In DrawingPanel2 getCanvas()");
        return bufferImage;

    } //public Graphics getCanvas()







    public void refreshCanvas(BufferedImage bi) {

        if(IDSSAppConstants.debug) {
            System.out.println("DrawingPanel2.refreshCanvas()");
            System.out.println("getSize().width  : " + getSize().width + "\n" +
                               "getSize().height : " + getSize().height + "\n" +
                               "bi.getWidth()    : " + bi.getWidth() + "\n" +
                               "bi.getHeight()    : " + bi.getHeight());


        } //if(IDSSAppConstants.debug)

        Graphics bufferGraphics = bufferImage.getGraphics();

        bufferGraphics.drawImage(bi,0,0,getSize().width,getSize().height,
                    0,0,bi.getWidth(),bi.getHeight(),this);

        repaint();

    } //public void refreshCanvas()





  public void clearBuffer() {

    Graphics g = bufferImage.getGraphics();

    int sizeX = getSize().width;
    int sizeY = getSize().height;

    g.setColor(Color.white);
    g.fillRect(leftMargin,topMargin,(sizeX-leftMargin-rightMargin),(sizeY-topMargin-bottomMargin));
    g.setColor(Color.black);


    repaint();

  } //public void clearBuffer()





  public void mousePressed (MouseEvent e) {

    //System.out.println("mouse pressed");
    x1 = e.getX();
    y1 = e.getY();

    x2 = x1;
    y2 = y1;

  }

  public void mouseReleased (MouseEvent e) {


    //System.out.println("mouse released");
    x2 = e.getX();
    y2 = e.getY();

    Graphics g = bufferImage.getGraphics();
    g.setColor(Color.black);
    g.setPaintMode();
    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));

    repaint();
    
  } //mouseReleased()




  public void mouseDragged (MouseEvent e) {

    //System.out.println("mouse dragged");
    Graphics g = getGraphics();
    g.setXORMode(Color.red);


    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));

    //x2,y2 changes with mouse dragging
    x2 = e.getX();
    y2 = e.getY();

    g.drawRect(Math.min(x1,x2),Math.min(y1,y2),Math.abs(x1-x2),Math.abs(y1-y2));

    g.setPaintMode();

  } //public void mouseDragged (MouseEvent e)


  public void mouseClicked (MouseEvent e) {}
  public void mouseEntered (MouseEvent e) {}
  public void mouseExited (MouseEvent e) {}
  public void mouseMoved (MouseEvent e) {}




/**
    public void drawGrid(Vector gridsVector,SurfaceColor sc) {

        for(int i=0;i<gridsVector.size();i++){
            Grid aGrid = (Grid) gridsVector.elementAt(i);
            drawGrid(aGrid,sc);
            setTitle(aGrid.getName());
        }

    } //public void drawGrid(Vector gridsVector,SurfaceColor sc)

**/






/** Method taken to Grid

    public void drawGrid(Grid grid,SurfaceColor sc) {


        if (!grid.isRead()) {
            grid.read();
        }

        System.out.println("In DrawingPanel2.drawGrid(Grid grid,SurfaceColor sc)");
        System.out.println("Grid size (nCols,Nrows) : " + grid.getNColumns() + ", " + grid.getNRows());

        BufferedImage bi = new BufferedImage (grid.getNColumns(),grid.getNRows(),BufferedImage.TYPE_INT_RGB);
        Graphics g2 = (Graphics) bi.getGraphics();

        double noData = grid.getNoDataValue();

        for(int i=0;i<grid.getZ().size();i++) { //rows of the grid

            Vector currentRow = (Vector) grid.getZ().elementAt(i);

            for(int j=0;j<currentRow.size();j++) {

                double zValue = Double.parseDouble(currentRow.elementAt(j).toString());

                if (Math.abs(zValue-noData) > 0.1) {

                    Color color = sc.getColor(zValue);
                    g2.setColor(color);
                    g2.fillRect(j,i,1,1);

                } //if (Math.abs(zValue-noData) > 0.1)

            } //for(int j=0;j<currentRow.size();j++)


        } //for(int i=0;i<z.size();i++)


        Graphics bufferGraphics = bufferImage.getGraphics();

        bufferGraphics.drawImage(bi,0,0,sizeX,sizeY,0,0,bi.getWidth(),bi.getHeight(),this);

        repaint();


    } //public void drawGrid(Grid grid,SurfaceColor sc)

**/



  public void drawXYGraph(double[] xValues, double[] yValues) {


    int x[] = new int[xValues.length];
    int y[] = new int[yValues.length];

    int sizeX = getSize().width;
    int sizeY = getSize().height;

    double xMax = getMax(xValues);
    double yMax = getMax(yValues);

    double xMin = getMin(xValues);
    double yMin = getMin(yValues);

    //mapping of yValues to device coordinates

    double temp;
    for (int i=0;i<xValues.length;i++) {
      temp = (sizeX-rightMargin-leftMargin)/(xMax-xMin)*(xValues[i]-xMin)+leftMargin;
      x[i] = (int) temp;
    }

    for (int i=0;i<xValues.length;i++) {
      temp = sizeY-(yValues[i]-yMin)*(sizeY-bottomMargin-topMargin)/(yMax-yMin)-bottomMargin;
      y[i] = (int) temp;
    }


    //Drawing polyline

    if (bufferImage == null)
      System.out.println("bufferImage is null!!");

    if (firstTime)
      setupPanel();

    Graphics g = bufferImage.getGraphics();


    System.out.println("Drawing polyline");

    g.setColor(Color.black);
    g.drawPolyline(x,y,x.length);


    repaint();

  }//public void drawXYGraph(double[] xValues, double[] yValues)


  private double getMax(double[] x) {

    double max = -9999999999999.0;
    
    for (int i=0;i<x.length;i++)
      if (x[i] > max)
        max = x[i];

    return max;

  }//private double getMax(double[] x)






  private double getMin(double[] x) {

    double min = 9999999999999.0;

    for (int i=0;i<x.length;i++)
      if (x[i] < min)
        min = x[i];

    return min;

  }//private double getMin(double[] x)








  public void componentResized (ComponentEvent e) {


    if (parentFrame != null) {

        System.out.println("Drawingpanel2 resized, parent not null");
        sizeX = getWidth();
        sizeY = getHeight();



        bufferImage = new BufferedImage (sizeX,sizeY,BufferedImage.TYPE_INT_RGB);

        if (bufferImage != null) {
          System.out.println("bufferImage recreated");
          Graphics bg = bufferImage.getGraphics();
          bg.setColor(Color.white);
          bg.fillRect(leftMargin,topMargin,(sizeX-leftMargin-rightMargin),(sizeY-topMargin-bottomMargin));
          bg.setColor(Color.black);

        }



        System.out.println("drawingpanel2:componentResized, sizeX,sizeY : " + sizeX + " ," + sizeY);

        clearBuffer();
        parentFrame.resizeCanvas();
    }
    else {
        System.out.println("Drawingpanel2 resized, parent is null");
        resizeDrawingPanel();

    }

  } //public void componentResized (ComponentEvent e)






  private void resizeDrawingPanel () {
  //public void componentResized (ComponentEvent e) {


    System.out.println("In resizeDrawingPanel()");

    int canvasX = getWidth();
    int canvasY = getHeight();

    int prevX = sizeX;
    int prevY = sizeY;

    System.out.println(canvasX + ", " + canvasY);

    BufferedImage aImage = bufferImage;

    // bufferGraphics = bufferImage.getGraphics();

    bufferImage = null;

    bufferImage = new BufferedImage (Math.max(canvasX,prevX),Math.max(canvasY,prevY),BufferedImage.TYPE_INT_RGB);
    //bufferImage = new BufferedImage (canvasX,canvasY,BufferedImage.TYPE_INT_RGB);

    Graphics bufferGraphics = bufferImage.getGraphics();
    bufferGraphics.setColor(Color.white);
    bufferGraphics.fillRect(leftMargin,topMargin,(canvasX-leftMargin-rightMargin),(canvasY-topMargin-bottomMargin));
    bufferGraphics.setColor(Color.black);

    //bufferGraphics.drawImage(aImage,0,0,canvasX,canvasY,this);
    bufferGraphics.drawImage(aImage,0,0,canvasX,canvasY,
                                    0,0,prevX,prevY,Color.white,this);


    sizeX = canvasX;
    sizeY = canvasY;

    repaint();

  } //public void resizeDrawingPanel ()




  public void componentHidden (ComponentEvent e) {}
  public void componentMoved (ComponentEvent e) {}
  public void componentShown (ComponentEvent e) {}





  private String getMouseCoords() {
  
    String a, b;
    
    a = new String("");
    b = new String("");

    a = String.valueOf(x2);
    b = String.valueOf(y2);
    mouseCoords = a + "," + b;

    return mouseCoords;

  } //private String getMouseCoords()





}

