package adecWatt.model;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import misc.Log;
import misc.Util;

public class InseeDB {

    // http://www.geonames.org/export/codes.html
    // http://download.geonames.org/export/dump/ (PPL)
    
    // ========================================
    static public class Insee {
	public String code, name;
	public double latitude, longitude;

	public Insee (String code, String name, double latitude, double longitude) {
	    this.code = code;
	    this.name = name;
	    this.latitude = latitude;
	    this.longitude = longitude;
	}
    }

    // ========================================
    private ArrayList<Insee> cities = new ArrayList<Insee> ();
    public InseeDB (Node node) {
	parse (node);
    }

    public ArrayList<Insee> getCities (String pattern) {
	pattern = Util.removeAccent (pattern.toLowerCase ().replaceAll ("-", " "));
	ArrayList<Insee> result = new ArrayList<Insee> ();
	for (Insee insee : cities)
	    if (Util.removeAccent (insee.name.toLowerCase ().replaceAll ("-", " ")).indexOf (pattern) >= 0 ||
		insee.code.indexOf (pattern) >= 0)
		result.add (insee);
	return result;
    }

    // ========================================
    static public InseeDB readDocument (URL url) {
	try {
	    return readDocument (url.openStream ());
	} catch (Exception e) {
	}
	return null;
    }
    static public InseeDB readDocument (InputStream stream) {
	try {
	    DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance ().newDocumentBuilder ();
	    Document document = documentBuilder.parse (stream);
	    document.normalizeDocument ();
	    return new InseeDB (document.getFirstChild ());
	} catch (Exception e) {
	    Log.keepLastException ("InseeDB::readDocument", e);
	    throw new IllegalArgumentException ("Not XML file input.");
	}
    }

    private void parse (Node node) {
	//XX insee =? node.getNodeName ()
	NodeList childrens = node.getChildNodes ();
	for (int i = 0; i < childrens.getLength (); i++) {
	    try {
		Node child = childrens.item (i);
		NamedNodeMap allFacets = child.getAttributes ();
		cities.add (new Insee (allFacets.getNamedItem ("code").getNodeValue (), allFacets.getNamedItem ("name").getNodeValue (),
				       Double.parseDouble (allFacets.getNamedItem ("lat").getNodeValue ()),
				       Double.parseDouble (allFacets.getNamedItem ("long").getNodeValue ())));
	    } catch (Exception e) {
	    }
	}
    }

    // ========================================
}

