package iDSS.gridDisp;

import java.awt.*;
import java.util.*;
import java.awt.image.*;
import java.text.*;
import javax.swing.*;

import iDSS.disp.*;



public class SurfaceColor {


    private Vector zValues;
    private Vector rValues;
    private Vector gValues;
    private Vector bValues;

    private int x0 = 20;
    private int y0 = 20;
    private int hGap = 2;
    private int tickLength = 5;
    private int cellWidth = 20;
    private int cellHeight = 2;
    private int stringLength = 30;
    private int legendWidth;
    private int legendHeight;
    private String legendTitle;
    private int numberOfTics = 5;

    private int type;
    public static int GENERAL = 0;
    public static int TIMECOLORSCHEMEUPTOAYEAR = 1;
    public static int DEM = 2;
    public static int FLOOD = 3;







    public SurfaceColor(String title,Vector z,Vector r, Vector g, Vector b) {
        //r,g,v and specified as Floats or Doubles from 0 to 1.0

        legendTitle = title;
        type = SurfaceColor.GENERAL;

        zValues = z;
        rValues = r;
        gValues = g;
        bValues = b;

        legendWidth = x0+cellWidth+tickLength+hGap+stringLength+x0;
        legendHeight = y0+256*cellHeight+y0;

    } //public SurfaceColor(Vector z,Vector r, Vector g, Vector b)












    public SurfaceColor(String title, int i) {

        //r,g,v and specified as Floats or Doubles from 0 to 1.0

        if(i == SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR) {

            legendTitle = title;
            type = SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR;

            zValues = new Vector();
            rValues = new Vector();
            gValues = new Vector();
            bValues = new Vector();

            double d = 365.0*24*60.0*60.0*1000.0;

            zValues.add(new Double(0));
            zValues.add(new Double(d*0.25));
            zValues.add(new Double(d*0.5));
            zValues.add(new Double(d*0.75));
            zValues.add(new Double(d));

            rValues.add(new Double(0));
            rValues.add(new Double(1));
            rValues.add(new Double(0.75));
            rValues.add(new Double(0.5));
            rValues.add(new Double(0));

            gValues.add(new Double(1));
            gValues.add(new Double(0));
            gValues.add(new Double(0));
            gValues.add(new Double(0));
            gValues.add(new Double(0));

            bValues.add(new Double(0));
            bValues.add(new Double(0.25));
            bValues.add(new Double(0.50));
            bValues.add(new Double(0.75));
            bValues.add(new Double(1.0));

            legendWidth = x0+cellWidth+tickLength+hGap+stringLength+x0;
            legendHeight = y0+256*cellHeight+y0;

        } //if(i = SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR)

        else {

            zValues = new Vector();
            rValues = new Vector();
            gValues = new Vector();
            bValues = new Vector();

            JOptionPane.showMessageDialog(null, "Surface color constructor with invalid option.\nGrids won't be drawn properly",
                                                "Warning",JOptionPane.WARNING_MESSAGE);

        } //else



    } //public SurfaceColor(Vector z,Vector r, Vector g, Vector b)









    public SurfaceColor(String title, double min, double max, int aType) {

        legendTitle = title;

        type = aType;

        zValues = new Vector();
        rValues = new Vector();
        gValues = new Vector();
        bValues = new Vector();

        zValues.add(new Double(min));
        zValues.add(new Double(min+(max-min)*0.25));
        zValues.add(new Double(min+(max-min)*0.5));
        zValues.add(new Double(min+(max-min)*0.75));
        zValues.add(new Double(max));

        if(type == SurfaceColor.DEM) {

            rValues.add(new Double(0));
            rValues.add(new Double(0));
            rValues.add(new Double(0));
            rValues.add(new Double(.5));
            rValues.add(new Double(1));

            gValues.add(new Double(0));
            gValues.add(new Double(.5));
            gValues.add(new Double(1));
            gValues.add(new Double(.5));
            gValues.add(new Double(0));

            bValues.add(new Double(1));
            bValues.add(new Double(0));
            bValues.add(new Double(0));
            bValues.add(new Double(0));
            bValues.add(new Double(0));

        } //if(type = SurfaceColor.DEM)

        else if(type == SurfaceColor.FLOOD) {

            rValues.add(new Double(0));
            rValues.add(new Double(0.5));
            rValues.add(new Double(1));
            rValues.add(new Double(0.5));
            rValues.add(new Double(0));

            gValues.add(new Double(1));
            gValues.add(new Double(0));
            gValues.add(new Double(0));
            gValues.add(new Double(0));
            gValues.add(new Double(0));

            bValues.add(new Double(0));
            bValues.add(new Double(0.25));
            bValues.add(new Double(0.50));
            bValues.add(new Double(0.75));
            bValues.add(new Double(1.0));

        } //else if(type = SurfaceColor.FLOOD)

        legendWidth = x0+cellWidth+tickLength+hGap+stringLength+x0;
        legendHeight = y0+256*cellHeight+y0;

    } //public SurfaceColor(Vector z,Vector r, Vector g, Vector b)









    public String getTitle() {

        return legendTitle;

    } //



    public int getLegendWidth() {

        return legendWidth;

    } //



    public int getLegendHeight() {

        return legendHeight;

    } //




    public Color getColor(double z) {

        Color color = new Color(0,0,0);

        double zMin = Double.parseDouble(zValues.elementAt(0).toString());
        double zMax = Double.parseDouble(zValues.elementAt(zValues.size()-1).toString());


        if((z>=zMin) && (z<=zMax)) {

            for(int i=0;i<(zValues.size()-1);i++) {

                double z1 = Double.parseDouble(zValues.elementAt(i).toString());
                double z2 = Double.parseDouble(zValues.elementAt(i+1).toString());

                if((z>=z1) && (z<=z2)) {

                    double r1 = Double.parseDouble(rValues.elementAt(i).toString());
                    double r2 = Double.parseDouble(rValues.elementAt(i+1).toString());

                    double g1 = Double.parseDouble(gValues.elementAt(i).toString());
                    double g2 = Double.parseDouble(gValues.elementAt(i+1).toString());

                    double b1 = Double.parseDouble(bValues.elementAt(i).toString());
                    double b2 = Double.parseDouble(bValues.elementAt(i+1).toString());

                    float r = (new Double((r2-r1)*(z-z1)/(z2-z1)+r1)).floatValue();
                    float g = (new Double((g2-g1)*(z-z1)/(z2-z1)+g1)).floatValue();
                    float b = (new Double((b2-b1)*(z-z1)/(z2-z1)+b1)).floatValue();

                    color = new Color(Math.abs(r),Math.abs(g),Math.abs(b));

                    break;

                }//if((z>z1) and (z<=z2))

            } //for(int i=0;i<(zVector.size()-1);i++)

        } //if((z>=zMin) && (z<=zMax))


        else if (z>zMax) {

            double rDouble = Double.parseDouble(rValues.elementAt(rValues.size()-1).toString());
            double gDouble = Double.parseDouble(gValues.elementAt(gValues.size()-1).toString());
            double bDouble = Double.parseDouble(bValues.elementAt(bValues.size()-1).toString());

            float r = (new Double(rDouble)).floatValue();
            float g = (new Double(gDouble)).floatValue();
            float b = (new Double(bDouble)).floatValue();

            color = new Color(Math.abs(r),Math.abs(g),Math.abs(b));

        } //else if (z>zMax)


        else if (z<zMin) {

            double rDouble = Double.parseDouble(rValues.elementAt(0).toString());
            double gDouble = Double.parseDouble(gValues.elementAt(0).toString());
            double bDouble = Double.parseDouble(bValues.elementAt(0).toString());

            float r = (new Double(rDouble)).floatValue();
            float g = (new Double(gDouble)).floatValue();
            float b = (new Double(bDouble)).floatValue();

            color = new Color(Math.abs(r),Math.abs(g),Math.abs(b));

        } //else if (z<zMin)

        return color;

    } //public Color getColor(double z)




    public void drawLegend(ImageDisplay imageDisplay) {


/**
        BufferedImage bi = imageDisplay.getCanvas();

        //BufferedImage bi = new BufferedImage (legendWidth,legendHeight,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) bi.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0,0,bi.getWidth(),bi.getHeight());

        double zMin = Double.parseDouble(zValues.elementAt(0).toString());
        double zMax = Double.parseDouble(zValues.elementAt(zValues.size()-1).toString());
        double zDiff = (zMax-zMin)/256;

        for (int i=0;i<256;i++) {

            Color c = getColor(zMin+(double)i*zDiff);
            g.setColor(c);
            g.fillRect(x0,y0+(255-i)*cellHeight,cellWidth,cellHeight);

        } //for (int i=0;i<256;i++)

        g.setColor(Color.black);

        DecimalFormat decimalFormat = new DecimalFormat("0.00");

        zDiff = (zMax-zMin)/(numberOfTics-1);

        for(int i=0;i<numberOfTics;i++) {

            //double z = Double.parseDouble(zValues.elementAt(i).toString());
            double z = zMin+(double)i*zDiff;
            int y = (new Double(256*cellHeight*(zMax-z)/(zMax-zMin)+y0)).intValue();
            String s = decimalFormat.format(z);


            if(type == SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR) {
                decimalFormat = new DecimalFormat("0");
                z = z/(1000*60*60*24);
                s = decimalFormat.format(z)+ " days";
            } //if(type = SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR)


            g.drawLine(x0+cellWidth,y,x0+cellWidth+tickLength,y);
            g.drawString(s,x0+cellWidth+tickLength+hGap,y);

        } //for(int i=0;i<zValues.siz();i++)

**/
        BufferedImage bi = getImage(imageDisplay);

        imageDisplay.refreshCanvas(bi);

    } //public void makeLegend()





    public BufferedImage getImage(ImageDisplay imageDisplay) {


        BufferedImage bi = imageDisplay.getCanvas();

        //BufferedImage bi = new BufferedImage (legendWidth,legendHeight,BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) bi.getGraphics();
        g.setColor(Color.white);
        g.fillRect(0,0,bi.getWidth(),bi.getHeight());

        double zMin = Double.parseDouble(zValues.elementAt(0).toString());
        double zMax = Double.parseDouble(zValues.elementAt(zValues.size()-1).toString());
        double zDiff = (zMax-zMin)/256;

        for (int i=0;i<256;i++) {

            Color c = getColor(zMin+(double)i*zDiff);
            g.setColor(c);
            g.fillRect(x0,y0+(255-i)*cellHeight,cellWidth,cellHeight);

        } //for (int i=0;i<256;i++)

        g.setColor(Color.black);

        DecimalFormat decimalFormat = new DecimalFormat("0.00");

        zDiff = (zMax-zMin)/(numberOfTics-1);

        for(int i=0;i<numberOfTics;i++) {

            //double z = Double.parseDouble(zValues.elementAt(i).toString());
            double z = zMin+(double)i*zDiff;
            int y = (new Double(256*cellHeight*(zMax-z)/(zMax-zMin)+y0)).intValue();
            String s = decimalFormat.format(z);


            if(type == SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR) {
                decimalFormat = new DecimalFormat("0");
                z = z/(1000*60*60*24);
                s = decimalFormat.format(z)+ " days";
            } //if(type = SurfaceColor.TIMECOLORSCHEMEUPTOAYEAR)


            g.drawLine(x0+cellWidth,y,x0+cellWidth+tickLength,y);
            g.drawString(s,x0+cellWidth+tickLength+hGap,y);

        } //for(int i=0;i<zValues.siz();i++)


        return bi;

    } //public BufferedImage getImage()






} //public class SurfaceColor 
