/*
 */
package usda.weru.weps;

import de.schlichtherle.io.File;
import de.schlichtherle.io.FileReader;
import java.awt.*;

import java.io.BufferedReader;
import java.util.StringTokenizer;
import java.util.Hashtable;
import java.util.Vector;

import org.apache.log4j.Logger;

/**
 * The stateMap class/object is responsible fot drawing the state boudaries for various US states
 * along with latitudinal/longitudinal details for every point along the various county boundaries
 * that eventually form the state boundaries.
 */
public class StateMap extends Polygon {
    String name;
    String stateId;
    String stateCode;
    double distance=0.0;
    float lat=0.0f;
    float lon=0.0f;
    String latitude;
    String latitudeSign="+";
    String longitude;
    String longitudeSign="-";
    Vector stateVec=new Vector();
    /**
     * stores the key mapped information for each state's data.
     */
    public static final Hashtable ht=new Hashtable();
    Vector countyVec=new Vector();

    /**
     * Default contructor
     */
    public StateMap() {
    }

    /**
     * Three argument constructor taking the name of the state, its ID string and the code name that
     * is assigned for that state whose StateMap is to be drawn.
     * @param name The name of the State whose Mapped boundaries are being drawn.
     * @param stateId The Id string assigned to the state.
     * @param stateCode The Code string with which the state is being identified.
     */
    public StateMap(String name, String stateId, String stateCode) {
        this.name=name;
        this.stateId=stateId;
        this.stateCode=stateCode;
    }

    /**
     * Converts the object to a String value and returns it.
     * @return The newly converted string value.
     */
    public String toString() {
        return name;
    }

    /**
     * Loads or populates the state data into the vector from the text file provided eg: states.txt.
     * @return The vector containing all objects containging the data for each state's name, ID & code.
     */
    public static Vector loadFile() {

        Vector mapVec=new Vector();

        String temp, outString;

        try {
            BufferedReader in=
                //new BufferedReader(new FileReader("states.bna"));
                new BufferedReader(new FileReader(new File("data", "states.txt").getCanOrAbsFile()));
//    		DataOutputStream out =
//	    	    //new DataOutputStream(new FileOutputStream("states.bin"));
//	    	    new DataOutputStream(new FileOutputStream("counties.bin"));

            StateMap sm=null;

            while ((temp=in.readLine()) != null) {
                StringTokenizer st=new StringTokenizer(temp, ",");
                if (st.countTokens() == 4) {
                    String stateId=st.nextToken().trim();
                    String name=st.nextToken().trim();
                    String stateCode=st.nextToken().trim();
                    sm=new StateMap(name, stateId, stateCode);
                    mapVec.add(sm);
                    ht.put(stateId.trim(), sm);
                    ht.put(name.trim(), sm);
                    ht.put(stateCode.trim(), sm);
                } else if (st.countTokens() != 0) {								// invalid line
                //System.err.println("SM_lF: invalid line " + st.countTokens() + " " + temp);
                }
            }
//            out.close();
            in.close();
        } catch (Exception e) {
            Logger.getLogger(StateMap.class).error(e);
        }

        return mapVec;
    }

    void setLonLat() {
        if (npoints == 0) {
            return;
        }
        java.awt.geom.Rectangle2D.Float r2df=(java.awt.geom.Rectangle2D.Float) this.getBounds2D();
        if (this.contains(r2df.x + r2df.width / 2, r2df.y + r2df.height / 2)) {
            lon=r2df.x + r2df.width / 2;
            lat=r2df.y + r2df.height / 2;
        } else if (this.contains(r2df.x + r2df.width / 4, r2df.y + r2df.height / 2)) {
            lon=r2df.x + r2df.width / 4;
            lat=r2df.y + r2df.height / 2;
        ////System.out.println("SM_sLL center out of county 1 " + this.name);
        } else if (this.contains(r2df.x + 3 * r2df.width / 4, r2df.y + r2df.height / 2)) {
            lon=r2df.x + 3 * r2df.width / 4;
            lat=r2df.y + r2df.height / 2;
        ////System.out.println("SM_sLL center out of county 2 " + this.name);
        } else if (this.contains(r2df.x + r2df.width / 2, r2df.y + r2df.height / 4)) {
            lon=r2df.x + r2df.width / 2;
            lat=r2df.y + r2df.height / 4;
        ////System.out.println("SM_sLL center out of county 3 " + this.name);
        } else if (this.contains(r2df.x + r2df.width / 2, r2df.y + 3 * r2df.height / 4)) {
            lon=r2df.x + r2df.width / 2;
            lat=r2df.y + 3 * r2df.height / 4;
        ////System.out.println("SM_sLL center out of county 4 " + this.name);
        } else {
            for (int idx=0; idx < npoints; idx++) {
                if (this.contains((float) xpoints[idx], (float) ypoints[idx])) {
                    lon=xpoints[idx];
                    lat=ypoints[idx];
                    break;
                }
            }
        ////System.out.println("SM_sLL center out of state 6!!!! " + this.name);
        }
        lon/=100000;
        lat/=100000;
    }

    /**
     * Compares and returns boolean values that fetches the results of comparison  between two objects.
     * @param obj The object to which the comparison is to happen.
     * @return True, if both object are equal else false.
     */
    public boolean equals(Object obj) {
        if (obj instanceof String) {
            return this.name.trim().equalsIgnoreCase(((String) obj).trim());
        } else if (obj instanceof StateMap) {
            return this.name.trim().equalsIgnoreCase(((StateMap) obj).name.trim());
        } else if (obj instanceof CountyMap) {
            return this.name.trim().equalsIgnoreCase(((CountyMap) obj).state.trim());
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 59 * hash + (this.name != null ? this.name.hashCode() : 0);
        hash = 59 * hash + (this.stateId != null ? this.stateId.hashCode() : 0);
        hash = 59 * hash + (this.stateCode != null ? this.stateCode.hashCode() : 0);
        return hash;
    }
    
    
}

