package iDSS.grids;

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

import iDSS.sm.*;
import iDSS.utils.*;




public class LCGrid2 implements GenericGrid, Serializable {

    private String name;

    private int units;
    private final int UNKNOWN = 0;
    private final int FT = 1;
    private final int IN = 2;
    private final int M = 3;
    private final int MM = 4;

    private double cellSize;
    private int nRows,nColumns;
    private double xLLCorner,yLLCorner;
    private double xURCorner,yURCorner;
    private double xLLC,yLLC,xURC,yURC;
    private String fileName = "";
    private File file;
    private boolean gridReadDone = false;
    private Vector z;





    public LCGrid2(String title, File aFile,Grid lcGrid,Hashtable smHashtable) {

        System.out.println("Creating LCGrid2 " + title);

/**

        //Test

        System.out.println("smHashtable.size() : " + smHashtable.size());

        Enumeration keys = smHashtable.keys();

        while(keys.hasMoreElements()) {

            String landClass = (String) keys.nextElement();
            String survivalModel = (String) smHashtable.get(landClass);
            System.out.println("landClass, survivalModel : " + landClass + ", " + survivalModel);

        } //while(keys.hasMoreElements())


        //Test ends

**/

        name = title;
        if(aFile != null) {
            file = aFile;
            fileName = aFile.toString();
        }

        units = lcGrid.getUnits();
        nRows = lcGrid.getNRows();
        nColumns = lcGrid.getNColumns();
        cellSize = lcGrid.getCellSize();

        xLLCorner = lcGrid.getxLLCorner();
        yLLCorner = lcGrid.getyLLCorner();

        xURCorner = (nColumns-1) * cellSize;
        yURCorner = (nRows-1) * cellSize;

        xLLC = xLLCorner+cellSize/2;
        yLLC = yLLCorner+cellSize/2;
        xURC = xLLC+(nColumns-1)*cellSize;
        yURC = yLLC+(nRows-1)*cellSize;

        z = new Vector();

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

            Vector currentRow = new Vector();

            for(int j=0;j<nColumns;j++) {

                int lcId = lcGrid.getIntValue(j,i);
                System.out.println("lcId : " + lcId);
                String lcString = String.valueOf(lcId);

                if(!lcString.endsWith(".0")) {
                    lcString = lcString + ".0";
                } //
                
                System.out.println("lcString : " + lcString);

                String smFileName = (String) smHashtable.get(lcString);

                System.out.println("LCGrid2.constructor(..), smFileName : " + smFileName);
                File smFile = new File(smFileName);

                if(smFile == null) {
                    System.out.println("LCGrid2.constructor(..), file not made from " + smFileName);
                }
                else {
                    System.out.println("LCGrid2.constructor(..), file made from " + smFileName);
                }

                SurvivalModel sm;
                sm = (SurvivalModel) ObjectReadWrite.read(smFile);

                if(sm == null) {
                    System.out.println("LCGrid2.constructor(..), sm not read from file");
                }
                else {
                    System.out.println("LCGrid2.constructor(..), sm read from file");
                }


                LandCover lc = new LandCover(lcId,sm);
                currentRow.add(lc);

            } //for(int j=0;j<nColumns;j++)

            z.add(currentRow);

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

        System.out.println("nRows/nColumns : " + nRows + "/" + nColumns);

    } //public LCGrid2(...)









    public LCGrid2() {

        name = "";
        file = null;
        fileName = null;

        units = 0;
        nRows = 0;
        nColumns = 0;
        cellSize = 0;

        xLLCorner = 0;
        yLLCorner = 0;

        xURCorner = 0;
        yURCorner = 0;

        xLLC = 0;
        yLLC = 0;
        xURC = 0;
        yURC = 0;

        z = new Vector();

    } //public LCGrid2()








    public String getName() {

        return name;

    } //public String getName()








    public LandCover getLandCover(int i,int j) {

        LandCover lc = null;


        if ((i>=0) && (i<nColumns) && (j>=0) && (j<nRows)) {

            Vector vector = (Vector) z.elementAt(j);
            lc = (LandCover)vector.elementAt(i);

        } //if ((i>=0) && (i<=nColumns) && (j>=0) && (j<=nRows))

        else {

            System.out.println("LCGrid2.getLandCover(), i,j : " + i + "," + j);
            System.out.println("LCGrid2.getLandCover(), nColumns,nRows : " + nColumns + "," + nRows);

        } //else

        return lc;

    } //public LandCover getLandCover(int i,int j)









    private void setLandCoverAt(int col,int row,LandCover lc) {

        Vector oneRow = (Vector) z.elementAt(row);
        oneRow.remove(col);
        oneRow.insertElementAt(lc,col);
        z.remove(row);
        z.insertElementAt(oneRow,row);

    } //private void setLandCoverAt(int col,int row,GridCell lc)







    public void setFile(File aFile) {

        if(aFile != null) {
            file = aFile;
            fileName = aFile.toString();
        }

    } //public void setFile(File file)







    public void appendHistory(Grid2 yearlyGrid,int year) {


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

            Vector oneRow = (Vector) z.elementAt(i);
            for(int j=0;j<oneRow.size();j++) {

                LandCover lc = (LandCover) oneRow.elementAt(j);
                GridCell gc = yearlyGrid.getGridCell(j,i);
                lc.appendHistory(year,gc);

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

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


    } //public void appendHistory(Grid2 yearlyGrid,int year)




















    public void writeLCGrid2Object() {

        if(file != null) {

            try {
                if(file.exists()) {

                    int option = JOptionPane.showConfirmDialog(null,
                                        "File already exists, overwrite?",
                                        "Confirm file overwrite",
                                        JOptionPane.YES_NO_CANCEL_OPTION,
                                        JOptionPane.QUESTION_MESSAGE);

                    switch(option) {

                        case JOptionPane.YES_OPTION:
                            file.delete();
                            break;

                        case JOptionPane.NO_OPTION:

                            file = FileNameDialog.getOutputFileName("Pick output file",null,null);
                            break;

                        case JOptionPane.CANCEL_OPTION:

                            file = null;
                            break;

                        default:
                            break;

                    } //switch(option)

                }//if(outFile.exists())

                if(file.createNewFile()) {
                    FileOutputStream f = new FileOutputStream(file);
                    ObjectOutputStream ooStream = new ObjectOutputStream(f);
                    ooStream.writeObject(this);
                    ooStream.flush();
                    f.close();
                }
                else
                    System.out.println("Failed to create file " + file.toString());

            } //try

            catch (FileNotFoundException fnfe) {
                System.out.print("In LCGrid2.writeGridObject()");
                System.out.println("File not found : " + fnfe);
            }

            catch (IOException ioe) {
                System.out.print("In LCGrid2.writeGridObject()");
                System.out.println("IOException : " + ioe);
            }

        } //if(file != null)

        else {

            JOptionPane.showMessageDialog(null,"LCGrid2 couldn't write, file is null",
                                            "Warning",JOptionPane.WARNING_MESSAGE);

        } //else


    } //public void writeLCGrid2Object(ObjectOutputStream ooStream)










    public static LCGrid2 readLCGrid2Object(File aFile) {

        LCGrid2 aGrid = new LCGrid2();

        try {
            if(aFile.exists()) {

                FileInputStream f = new FileInputStream(aFile);
                ObjectInputStream oiStream = new ObjectInputStream(f);
                aGrid = (LCGrid2)oiStream.readObject();
                f.close();

            }//if(!inFile.exists())

            else {
                System.out.println("Input file " + aFile.toString() + " doesn't exist");
            }

        } //try

        catch (FileNotFoundException fnfe) {
            System.out.print("In LCGrid2.readGridObject()");
            System.out.println("File not found : " + fnfe);
        }

        catch (IOException ioe) {
            System.out.print("In LCGrid2.readGridObject()");
            System.out.println("IOException : " + ioe);
        }

        catch(ClassNotFoundException cnfe) {
            System.out.print("In LCGrid2.readGridObject()");
            System.out.println("ClassNotFoundException : " + cnfe);
        }

        catch(ClassCastException cce) {
            System.out.println("ClassCastException : " + cce);
            return null;
        }


        aGrid.gridIsRead(true);
        return aGrid;

    } //public static void readLCGrid2Object()




    public boolean isGridRead() {

        return gridReadDone;

    } //public boolean isGridRead()



    private void gridIsRead(boolean b) {

        gridReadDone = b;

    } //private void gridIsRead(boolean b)





    public void describe() {

        System.out.println("Describing LCGrid2");

        System.out.println("\nName        = " + name +
                           "\nnRows       = " + nRows +
                           "\nnColumns    = " + nColumns +
                           "\nxLLCorner   = " + xLLCorner +
                           "\nyLLCorner   = " + yLLCorner +
                           "\ncellSize    = " + cellSize);

    } //public void describe()









    public Grid getGrid(String parameter,int year) {

        Grid aGrid = new Grid(name+":"+parameter + ":" + year,1,units,null);

        Vector z2 = new Vector();

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

            Vector oneRow = (Vector) z.elementAt(i);
            Vector oneRow2 = new Vector();

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

                LandCover lc = (LandCover) oneRow.elementAt(j);
                String oneCell = lc.getValue(year,parameter);
                oneRow2.add(oneCell);

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

            z2.add(oneRow2);

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

        aGrid.setGrid(xLLCorner,yLLCorner,cellSize,z2,nRows,nColumns);
        aGrid.gridIsRead(true);

        return aGrid;

    } //public Grid getGrid(String datacategory)






    public Vector getGridVector() {

        Vector vector = new Vector();
        vector.add(name);
        vector.add(fileName);

        return vector;
    }





    public String getFileName() {

        return fileName;

    }



    public SurvivalModel getSurvivalModel(int col,int row) {

        //System.out.println("LCGrid2.getSurvivalModel(), col,row : " + col + "," + row);

        LandCover lc = getLandCover(col,row);
        SurvivalModel sm = lc.getSurvivalModel();
        return sm;

    } //public SurvivalModel getSurvivalModel(int col,int row)




    public Enumeration getYears() {

        Enumeration years = null;

        if(z.size()>0) {
            Vector firstRow = (Vector) z.elementAt(0);
            if(firstRow.size()>0) {
                LandCover firstLCCell = (LandCover) firstRow.elementAt(0);
                years = firstLCCell.getYears();

            }
        }


        return years;

    } //public Enumeration getYears()



} //public class LCGrid2
