package usda.weru.weps.location;

import javax.measure.Measurable;
import javax.measure.Measure;
import javax.measure.quantity.Length;
import javax.measure.unit.SI;
import org.apache.log4j.Logger;
import org.jscience.geography.coordinates.LatLong;
import usda.weru.gis.GISUtil;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class CligenStation implements Station {

    private static final Logger LOGGER = Logger.getLogger(CligenStation.class);
    private final LatLong c_latlong;
    private final String c_name;
    private final long c_state;
    private final long c_id;
    private final Measurable<Length> c_elevation;

    /**
     *
     * @param latlong
     * @param elevation
     * @param name
     * @param state
     * @param id
     */
    public CligenStation(LatLong latlong, Measurable<Length> elevation, String name, long state, long id) {
        if (latlong == null) {
            LOGGER.warn("Latlong is null.  Attempting to find value in Cligen data model for state="
                    + state + ", id=" + id + ".");
            CligenStation temp = CligenDataModel.getInstance().getStation(state, id);
            if (temp != null) {
                latlong = temp.getLatLong();
                LOGGER.warn("Latlong value found. " + latlong);
            } else {
                LOGGER.error("No latlong found for state=" + state + ", id=" + id + ".");
            }
        }
        c_latlong = latlong;
        c_elevation = elevation;
        c_name = name;
        c_state = state;
        c_id = id;

    }

    /**
     *
     * @param name
     * @param state
     * @param id
     */
    public CligenStation(String name, long state, long id) {
        this(null, null, name, state, id);

    }

    @Override
    public String getDisplayName() {
        return c_name;
    }

    /**
     *
     * @return
     */
    public String getName() {
        return c_name;
    }

    @Override
    public LatLong getLatLong() {
        return c_latlong;
    }

    /**
     *
     * @return
     */
    @Override
    public Measurable<Length> getElevation() {
        return c_elevation;
    }

    /**
     *
     * @return
     */
    public long getId() {
        return c_id;
    }

    /**
     *
     * @return
     */
    public long getState() {
        return c_state;
    }

    /**
     *
     * @return
     */
    @Override
    public String toString() {
        return c_state + " " + String.valueOf(c_id) + " " + c_name;
    }

    /**
     *
     * @param obj
     * @return
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final CligenStation other = (CligenStation) obj;
        if (this.c_state != other.c_state) {
            return false;
        }
        if (this.c_id != other.c_id) {
            return false;
        }
        return true;
    }

    /**
     *
     * @return
     */
    @Override
    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + (int) (this.c_state ^ (this.c_state >>> 32));
        hash = 89 * hash + (int) (this.c_id ^ (this.c_id >>> 32));
        return hash;
    }

    /**
     *
     * @param station
     * @return
     */
    public static String serialize(CligenStation station) {
        if (station != null) {
            StringBuilder buffer = new StringBuilder();

            //latlong
            buffer.append(station.getLatLong() != null ? GISUtil.format(station.getLatLong()) : "");
            buffer.append("|");
            //state
            buffer.append(Long.valueOf(station.getState()));
            buffer.append("|");
            //id
            buffer.append(Long.valueOf(station.getId()));
            buffer.append("|");
            //name
            buffer.append(station.getDisplayName() != null ? station.getDisplayName() : "");
            buffer.append("|");
            //elevation
            buffer.append(station.getElevation() != null ? station.getElevation().doubleValue(SI.METER) : "");

            return buffer.toString();
        }
        return null;
    }

    /**
     *
     * @param text
     * @return
     */
    public static CligenStation deserialize(String text) {
        if (text != null) {
            String[] parts = text.split("\\|");
            int i = 0;
            //latlong
            LatLong latlong = GISUtil.parse(parts[i++]);

            //state
            long state = Long.valueOf(parts[i++].trim());

            //id
            long id = Long.valueOf(parts[i++].trim());

            //name
            String name = parts[i++].trim();
            name = name.length() > 0 ? name : null;

            Measurable<Length> elevation = null;
            try {
                double elevationMeters = Double.valueOf(parts[i++].trim());
                elevation = Measure.valueOf(elevationMeters, SI.METER);
            } catch (Exception e) {
                //no elevation problem
            }
            //TODO: include elevation
            return new CligenStation(latlong, elevation, name, state, id);

        }
        return null;
    }

}
