package usda.weru.remoteDataAccess.csip.polygon;

import java.awt.geom.Point2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import systems.uom.common.USCustomary;
import usda.weru.gis.latlong.LatLong;
import usda.weru.remoteDataAccess.RdaHierarchicalItem;
import usda.weru.remoteDataAccess.csip.CsipHierarchicalItem;
import usda.weru.remoteDataAccess.csip.CsipInputController;
import usda.weru.remoteDataAccess.csip.CsipInterface;
import usda.weru.remoteDataAccess.exceptions.RdaConnectException;
import usda.weru.util.ConfigData;
import usda.weru.weps.RunFileData;
import usda.weru.weps.Weps;

/**
 *
 * @author mhaas
 */
public abstract class CsipInputContPolygon extends CsipInputController implements PropertyChangeListener {
    
    protected ArrayList<String> serviceResults;

    protected String polygonPropName;
    protected ArrayList<Point2D.Double> polygon;
    protected LatLong polygonCenter;
    
    public CsipInputContPolygon (boolean fromSubClass) {
        super ();

        polygonPropName = null;
        polygon = null;
        csipIf = getNewCsipInterface();
        serviceResults = null;
    }
    
    protected void setPolygonPropName (String propName) {
        polygonPropName = propName;
    }
    
    public void setPolygon (LatLong latlon) {
        polygonCenter = latlon;
        polygon = buildPolygon(latlon);
        ((CsipInterfacePolygon)csipIf).setPolygon(polygonCenter, polygon);
    }
    
    public ArrayList<Point2D.Double> getPolygon () {
        return polygon;
    }
    
    public LatLong getPolygonCenter () {
        return polygonCenter;
    }
    
    public ArrayList<Point2D.Double> buildPolygon (LatLong latlon) {
        
        ArrayList<Point2D.Double> retPoly = null;
        String cdVal = ConfigData.getDefault().getData(polygonPropName);

        if (latlon != null && cdVal != null) {
            double polygonSize = Double.valueOf(cdVal);
            // cdVal is in acres.
            // 1 acre = .004047 km squared
            // 90 degrees/10,000 km  = .009 degree/km conversion factor between degrees and km.
            polygonSize = polygonSize * .004047; // km squared
            polygonSize = Math.sqrt(polygonSize); // km
            polygonSize = polygonSize * .009; // degrees (per edge)

            final double polyWidth = polygonSize; // degrees
            final double polyHeight = polygonSize; // degrees

            double lat = latlon.latitudeValue(USCustomary.DEGREE_ANGLE);
            double lon = latlon.longitudeValue(USCustomary.DEGREE_ANGLE);

            retPoly = new ArrayList<>();

            retPoly.add(new Point2D.Double(lon + (polyWidth / 2), 
                                           lat + (polyHeight / 2) ));
            retPoly.add(new Point2D.Double( retPoly.get(0).x - polyWidth, 
                                           retPoly.get(0).y ));
            retPoly.add(new Point2D.Double( retPoly.get(0).x - polyWidth, 
                                           retPoly.get(0).y - polyHeight ));
            retPoly.add(new Point2D.Double( retPoly.get(0).x, 
                                           retPoly.get(0).y - polyHeight ));
        }
        
        return retPoly;
    }
    
    public void addPropertyChangeSupport () {
        String s = this.interfaceName;
        Weps.getInstance().getRunFileData().addPropertyChangeListener(RunFileData.StrLatLong, this);
        ConfigData.getDefault().addPropertyChangeListener(polygonPropName, this);
    }
    
    @Override
    public void setInterfaceName (String interfaceName) {
        super.setInterfaceName(interfaceName);
        csipIf.setInterfaceName(interfaceName);
    }

    @Override
    protected abstract CsipInterface getNewCsipInterface();

    @Override
    public File getFile(RdaHierarchicalItem item) throws RdaConnectException {
        return csipIf.callCsipGetRecord(item.getName(), item.getParentPath());
    }

    @Override
    protected void loadChildren(RdaHierarchicalItem rootItem) throws RdaConnectException {
        // Not required for Soil, Prism
        int i = 1;
    }
    
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
    }
    
    @Override
    protected RdaHierarchicalItem initializeData (RdaHierarchicalItem rootItem) throws RdaConnectException {
        // serviceResults should be already set from getCatalog call
        if (polygon != null) {
            if (serviceResults == null) {
                serviceResults = csipIf.callCsipCatalog();
                if (rootItem instanceof CsipHierarchicalItem) {
                    for (String result : serviceResults) {
                        ((CsipHierarchicalItem)rootItem).addPath (result);
                    }
                }
            }
        return rootItem;
        }
        return null;
    }

}
