/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package usda.weru.weps.location;

import de.schlichtherle.io.File;
import de.schlichtherle.io.FileReader;
import java.beans.PropertyChangeEvent;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.util.LinkedList;
import java.util.List;
import javax.measure.unit.NonSI;
import org.apache.log4j.Logger;
import org.jscience.geography.coordinates.LatLong;
import usda.weru.util.ConfigData;

/**
 *
 * @author Joseph Levin <joelevin@weru.ksu.edu>
 */
public class WindgenDataModel extends AbstractStationDataModel{
    private final static Logger LOGGER = Logger.getLogger(WindgenDataModel.class);

    private final Object DATA_LOCK = new Object();

    private static WindgenDataModel c_instance;

    private List <WindgenStation> c_stations;

    public static final synchronized WindgenDataModel getInstance(){
        if(c_instance == null){
            c_instance = new WindgenDataModel();
        }
        return c_instance;
    }

    public WindgenStation getStation(long id){
        for(WindgenStation station : stations()){
            if(station.getWBan() == id){
                return station;
            }
        }
        return null;
    }

    @Override
    protected void configDataPropertyChange(PropertyChangeEvent event) {
        super.configDataPropertyChange(event);

        if(ConfigData.WinIndex.equals(event.getPropertyName())){
            //the backing data has changed.
            clearStations();
        }
        else if(ConfigData.GISData.equals(event.getPropertyName())){
            fireGISDataChanged();
        }
    }

    private void clearStations(){
        synchronized (DATA_LOCK){
            if(c_stations == null){
                //nothing has changed
                return;
            }            
            c_stations = null;
        }
        clearCache();
        fireStationDataChanged();
    }

    public List<WindgenStation> stations(){
        //lock around the data
        synchronized (DATA_LOCK){
            if (c_stations == null){
                c_stations = new LinkedList<WindgenStation>();
                readFromFile(c_stations);
            }
            return c_stations;
        }
    }

    private void readFromFile(List<WindgenStation> stations){
        String path = ConfigData.getDefault().getDataParsed(ConfigData.WinIndex);
        if(path == null){
            return;
        }
        File file = new File(path);
        if(!file.canRead()){
            LOGGER.warn("Can not read file: " + file.getAbsolutePath());
        }
        BufferedReader in = null;
        try {
                in = new BufferedReader(new FileReader(file.getCanOrAbsFile()));
                for (String line = in.readLine(); line != null; line = in.readLine()) {
                    line = line.trim();
                    if(line.startsWith("#") || line.length() == 0){
                        //skip comments and blank lines
                        continue;
                    }
                    
                    String[] parts = line.split("\\s+");

                    int offset = 0;
                    double lat = parseCoordinate(parts, offset + 0);
                    double lon = parseCoordinate(parts, offset + 3);

                    LatLong latlong = LatLong.valueOf(lat, lon, NonSI.DEGREE_ANGLE);

                    long id = Long.parseLong(parts[offset + 12].trim());

                    String country = parts[offset + 13].trim();
                    String state = parts[offset + 14].trim();
                    String name = join (parts, offset +15);


                    WindgenStation station = new WindgenStation(latlong, id, country, state, name);

                    if(!stations.contains(station)){
                        stations.add(station);
                    }
                    else{
                        LOGGER.warn("Duplicate windgen station id.  Skipping record: " + station);
                    }

                }

                in.close();
            }
            catch (FileNotFoundException fnfe) {
                LOGGER.error("Wingen index file not found:" + file.getPath());
            }
            catch (Exception e) {
                LOGGER.error("Error reading the wingen index file:" + file.getPath(), e);
            }
        finally{
            if(in != null){
                try{
                    in.close();
                }
                catch(Exception e){
                    LOGGER.error("Unable to close stream.", e);
                }
            }
        }
    }

    private String join(String[] parts, int start){
        StringBuffer buffer = new StringBuffer();
        for (int i = start; i < parts.length; i++){
            buffer.append(parts[i]);
            buffer.append(" ");
        }
        return buffer.toString().trim();

    }

    private double parseCoordinate(String[] parts, int start){
        double degree = Double.parseDouble(parts[start].trim());
        double minutes = Double.parseDouble(parts[start + 1].trim());

        double value = degree + (minutes / 60);

        String quadrant = parts[start + 2].trim();
        if("S".equals(quadrant) || "W".equals(quadrant)){
            value = value * -1;
        }

        return value;
    }




}
