// Example of a layer XML document:
// 
// http://wildfire-dev.atgis.com.au/xml/load/74
//
// <layer id="74" name="My First Test" description="Actually about 100th!" created="1211256808" updated="1211256808" published="f" schema="1">
//   <schema id="1" name="Hydrants" description="Records the location of fire hydrants" type="point">
//     <field id="2" name="access" prompt="Access" default="" repeat_last="t" type="text" length="20" required="t">
//        <option name="Unrestricted" value="1"/>
//        <option name=" No Acce" value="2"/>
//        <option name=" 4wd Acce" value="3"/>
//        <option name=" 2WD Acce" value="4"/>
//        <option name=" Foot Acce" value="5"/>
//        <option name=" Unknown" value="6"/>
//      </field>
//     <field id="3" name="access_surface" prompt="Access surface" default="bitumen" repeat_last="t" type="text" length="20" required="f">
//        <option name="Bitumen" value="1"/>
//        <option name=" Gravel" value="2"/>
//        <option name=" Mineral Earth" value="3"/>
//        <option name=" Other" value="4"/>
//      </field>
//      <field id="4" name="access_condition" prompt="Access Condition" default="" repeat_last="t" type="text" length="20" required="f">
//        <option name="Managed" value="1"/>
//        <option name=" Unmanaged" value="2"/>
//        <option name=" Private Acce" value="3"/>
//        <option name=" Weather Affected" value="4"/>
//      </field>
//        <field id="5" name="hydrant_id" prompt="Hydrant Id" default="" repeat_last="f" type="text" length="12" required="f"/>
//        <field id="1" name="type" prompt="Hydrant type" default="Urban" repeat_last="t" type="text" length="10" required="t">
//        <option name="Urban" value="1"/>
//        <option name=" Rural" value="2"/>
//      </field>
//      <field id="6" name="hydrant_pressure" prompt="hydrant pressure" default="" repeat_last="t" type="text" length="10" required="f">
//        <option name="Unknown" value="1"/>
//        <option name=" Variable" value="2"/>
//      </field>
//    </schema>
//    <features>
//      <feature hydrant_id="A really good hydrant.  Red.">
//        <geometry type="point">
//          <point lon="145.5832" lat="-17.272"/>
//        </geometry>
//      </feature>
//    </features>
//  </layer>

function ucfirst( str ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: ucfirst('kevin van zonneveld');
    // *     returns 1: 'Kevin van zonneveld'
 
    var f = str.charAt(0).toUpperCase();
    return f + str.substr(1, str.length-1);
}

function EmptyNode(node)
{
    while (node.firstChild) {
	node.removeChild(node.firstChild);
    }
}

function SetNodeTextById(id, text)
{
    var node = document.getElementById(id);
    EmptyNode(node);
    node.appendChild(document.createTextNode(text));
    return node;
}

/*----------------------------------------------------------------------
 * globals 
 *----------------------------------------------------------------------*/
var blueDotIcon;
var digitize = new Object();
digitize.layerSchema;
digitize.openLayerForm;  // form node
digitize.openLayerDiv;   // parent div node
digitize.layer = null;  /* contains .features .schema */
digitize.isDirty = false;
digitize.modeListeners = [];  /* list of mode-specific gmap listeners */
digitize.pointMarker = null;  /* created in Init */
digitize.activeLine = null;
digitize.lineMode = 0;  // 0 new line, 1 extending

/* Open a dialog to start digitizing */
digitize.createLayer = function DigitizeCreateLayer()
{
    if (digitize.layerSchema == null) {
	digitize.loadLayerSchema(digitize.createLayer); // call me back
	return;
    }
    digitize.closeLayer();  // close any open layer

    var schema = digitize.layerSchema;
    schema.onSave = function() {
	digitize.loadNewLayer(this);
    }
    schema.onCancel = function() {
	digitize.closeLayerProperties();
    }
    schema.setReadOnly('schema_id',false);
    schema.showDeleteButton(false);
    digitize.layerSchema.resetValue();
    digitize.openLayerDiv.style.display = 'block';
}

digitize.loadNewLayer = function DigitizeLoadNewLayer(schema)
{
    var url = '/xml/save/0';
    var request = GXmlHttp.create();
    request.open("POST", url, true);
    request.setRequestHeader("Content-type", "text/xml");
    request.onreadystatechange = function() {
	if (request.readyState==4) {
	    digitize.closeLayerProperties();
	    var xml = request.responseText;
	    var dom = GXml.parse(xml);
	    var layer = dom.documentElement;
	    digitize.loadLayerXml(layer);
	    digitize.reloadIndex();
	}
    }
    request.send(schema.getFormXml(digitize.openLayerForm));
}

/*
 * Create a schema object from the schema DOM node
 */

/*
digitize.setSchema = function DigitizeSetSchema(schema)
{
    digitize.schema = new Object();
    digitize.schema.name = schema.getAttribute('name');
    digitize.schema.type = schema.getAttribute('type');
}
*/

/*
 * featureType is point/line/polygon
 * Unpack a single feature.  Returns a Feature subclass 
 * Point Line or Polygon
 */
/*
digitize.createFeature = function DigitizeCreateFeature(featureType, featureNode)
{
    var feature;
    if (featureType=='point')
    {
	feature = new Point();
    }
    feature.loadXml(featureNode);
    return feature;
}
*/
/*
 * Unpack the geometry objects from the geometry DOM node
 */
/*
digitize.setFeatures = function DigitizeSetFeatures(featureType, featureNodeList)
{
    digitize.features = new Array();
    for (var i=0;i<featureNodeList.length;i++) {
	var featureNode = featureNodeList[i];
	// could check featureType == featureNode.getElementsByTagName('geometry')[0].getAttribute('type');
	var feature = digitize.createFeature(featureType, featureNode);
	digitize.features[i]=feature;
    }
}
*/
/* 
 * set the current layer to be digitized
 *   using an XML dom which specifies the layer
 */
digitize.loadLayerXml = function DigitizeLoadXml(node)
{
    digitize.layer = new Layer();
    digitize.layer.loadXml(node);
    digitize.layer.featureForm= digitize.layer.schema.getForm({deleteButton: true});

    digitize.closeLayerProperties();
    digitize.loadLayerInfo();

     // show div
    var layerEditDiv = document.getElementById('layeredit');
    layerEditDiv.style.display = 'block';
    digitize.setMode(digitize.layer.schema.type, false);

    // show feature geometry
    digitize.layer.show();

    // reload the index (why?)
    //    digitize.reloadIndex();
    map.disableDoubleClickZoom();  // disenable double-click zoom while editing is possible
}

digitize.loadLayerInfo = function DigitizeLoadLayerInfo()
{
    SetNodeTextById('layeredit_title', digitize.layer.name);
    SetNodeTextById('layeredit_info', digitize.layer.schema.name);
    SetNodeTextById('layeredit_description', digitize.layer.description);
    digitize.updateActionMenu();
}

/*
 * type is point, line or polygon
 * selected is true or false
 */
digitize.setMode = function DigitizeSetMode(type, selected) 
{
    // clear mode listeners
    while (digitize.modeListeners.length>0)GEvent.removeListener(this.modeListeners.pop());

    // disable editing
    if (digitize.editShape) {
	digitize.editShape.disableEditing();
	digitize.editShape = null;
    }

    // clear any overlays
    map.removeOverlay(digitize.pointMarker);

    // reset modes
    digitize.lineMode = 0;
    digitize.activeLine = null;

    var mapDiv = document.getElementById('map');
    if (selected) {
	map.disableDragging();
	document.onkeyup = digitize.onKeyUp;
	document.ondblclick = digitize.onDoubleClick;
    } else {
	map.enableDragging();
	document.onkeyup = null;
	document.ondblclik = null;
    }

    log(type+(selected ? 'selected' : 'deselected'));
    if (type=='point') {
        if (selected) {
	    digitize.modeListeners.push(GEvent.addListener(map, 'mousemove', digitize.pointMouseMove));
	    digitize.modeListeners.push(GEvent.addListener(map, 'mouseout', digitize.pointMouseOut));
	    digitize.modeListeners.push(GEvent.addListener(map, 'mouseover', digitize.pointMouseOver));
	    digitize.modeListeners.push(GEvent.addListener(map, 'click', digitize.pointClick));
        }
    } else if (type=='line') {
        if (selected) { 
            digitize.modeListeners.push(GEvent.addListener(map, 'click', digitize.lineClick));
	    // for ie, maybe dblclick does work (and is required?).  For FF, it doesn't and isn't
	    //digitize.modeListeners.push(GEvent.addListener(map, 'dblclick', digitize.lineDoubleClick)); 
	    //digitize.modeListeners.push(GEvent.addListener(map, 'singlerightclick', digitize.lineDoubleClick));
	    //digitize.modeListeners.push(GEvent.addDomListener(document.getElementById('map'), 'keypress', function() {alert('keypress');}));
        }
    } else if (type=='polygon') {
	if (selected) {
	    digitize.modeListeners.push(GEvent.addListener(map, 'click', digitize.polygonClick));
	    //digitize.modeListeners.push(GEvent.addListener(map, 'dblclick', digitize.polygonDoubleClick)); 
	    //	    digitize.modeListeners.push(GEvent.addListener(map, 'keypress', digitize.polygonKeyPress));
	}
    } else {
	alert(type+' not supported');
    }

    SetNodeTextById('layeredit_addtype', 'Add '+ucfirst(type));

    // note we could avoid loop if we stored the last 
    // displayed icon and hid it.
    var div = document.getElementById('layeredit_add');
    var images = div.getElementsByTagName('img');
    for (var i=0;i<images.length;i++) {
	images[i].style.display = 'none';
    }
    var id = 'layeredit_'+type;
    if (selected) {
	id+='_selected';
    }
    var img = document.getElementById(id);
    img.style.display = 'block';
    digitize.mapMode = type;
    digitize.mapModeSelected = selected;
}

digitize.onDoubleClick = function Digitize_onDoubleClick()
{
    if (digitize.lineMode==1) {
	var point = digitize.activeLine.vertices[digitize.activeLine.vertices.length-1];
	if (digitize.mapMode=='line') {
	    digitize.lineDoubleClick(digitize.activeLine, point);
	} else if (digitize.mapMode=='polygon') {
	    digitize.polygonDoubleClick(digitize.activeLine, point);
	}
    }
}
digitize.onKeyUp = function Digitize_onKeyUp(e)
{
    var keyCode = (window.event) ? window.event.keyCode : e.keyCode;
    log(keyCode + " key up");
    if (keyCode==27 && digitize.lineMode==1) {
	var point = digitize.activeLine.vertices[digitize.activeLine.vertices.length-1];
	if (digitize.mapMode=='line') {
	    digitize.lineDoubleClick(digitize.activeLine, point);
	} else if (digitize.mapMode=='polygon') {
	    digitize.polygonDoubleClick(digitize.activeLine, point);
	}
    }
}

/*
digitize.showFeatures = function DigitizeShowFeatures()
{
    for (var i=0;i<digitize.features.length;i++) {
	digitize.features[i].show();
    }
}
*/

/*
 * Stop digitizing - close the current layer, hide the controls
 */
digitize.closeLayer = function DigitizeCloseLayer()
{
    log('closeLayer');
    map.closeInfoWindow();
    if (digitize.layer!=null) {
	if (digitize.isDirty) digitize.saveLayer();
	digitize.layer.dispose();
	digitize.layer = null;
    }
    var div = document.getElementById('layeredit');
    div.style.display = 'none';
    map.enableDoubleClickZoom();  // re-enable double-click zoom which was off during editing
}

digitize.closeLayerProperties = function DigitizeCloseLayerProperties()
{
    if (digitize.openLayerDiv!=null) {
	digitize.openLayerDiv.style.display = 'none';
    }
}

digitize.init = function DigitizeInit()
{
    blueDotIcon = new GIcon();
    blueDotIcon.image = "http://maps.google.com/mapfiles/ms/icons/blue-dot.png";
    blueDotIcon.shadow = "http://maps.google.com/mapfiles/ms/icons/msmarker.shadow.png";
    blueDotIcon.shadowSize = new GSize(59, 32);
    blueDotIcon.iconSize = new GSize(32, 32);
    blueDotIcon.iconAnchor = new GPoint(16, 32);
    blueDotIcon.infoWindowAnchor = new GPoint(16, 32);

    blueIcon = new GIcon(blueDotIcon);
    blueIcon.image = "http://maps.google.com/mapfiles/ms/icons/blue.png";

    digitize.pointMarker = new GMarker(map.getCenter(), blueIcon);
    digitize.reloadIndex();
}

digitize.reloadIndex = function DigitizeReloadIndex()
{
    var now = new Date();  // avoid caching
    var url = '/xml/list/'+now.getTime();
    var request = GXmlHttp.create();
    request.open("GET", url, true);
    request.onreadystatechange = function() {
	if (request.readyState==4) {
	    var xml = request.responseText;
	    var dom = GXml.parse(xml);
	    digitize.loadIndex(dom);
	}
    }
    request.send(null);
}

digitize.loadIndex = function DigitizeLoadIndex(dom)
{
    var div = document.getElementById('layer_list');
    EmptyNode(div);
    var layers = dom.getElementsByTagName('layer');
    var i;
    for (i=0;i<layers.length;i++) {
	div.appendChild(digitize.createIndexEntry(layers[i]));
    }
}

digitize.createIndexEntry = function DigitizeCreateIndexEntry(layer)
{
    var name = layer.getAttribute('name');
    var layerId = layer.getAttribute('id');
    var node = document.createElement('div');
    var link = document.createElement('a');
    var text = document.createTextNode(name);
    var img = document.createElement('img');
    img.src = '/images/tinypen.gif';
    img.className = 'icon';
    node.className = 'customlayer';
    if (layer.getAttribute('published')=='t') {
	node.className+=' published';
    }
    link.onclick = function () {
	digitize.loadLayerById(layerId);
    }
    link.appendChild(img);
    link.appendChild(text);
    node.appendChild(link);
    return node;
}

digitize.loadLayerById = function DigitizeLoadLayerById(layerId)
{
    digitize.closeLayer();  // close any open layer
    { // if (digitize.layer == null) {  // only if not currently open
        var url = '/xml/load/'+layerId;
        var request = GXmlHttp.create();
        request.open("GET", url, true);
        request.onreadystatechange = function() {
            if (request.readyState==4) {
	        var xml = request.responseText;
	        var dom = GXml.parse(xml);
	        var layer = dom.documentElement;
	        digitize.loadLayerXml(layer);
	    }
        }
        request.send(null);
    }
}

digitize.setDirty = function DigitizeSetDirty ()
{
    // REVISIT - how about resetting timer if already running?
  if (!digitize.isDirty) {
    digitize.isDirty = true;
    digitize.saveTimer = setTimeout(digitize.saveLayer, 5000);
  }
}

digitize.saveLayer = function DigitizeSaveLayer()
{
    if (digitize.isDirty) {
	clearTimeout(digitize.saveTimer);
	digitize.isDirty = false;
    }

    var url = '/xml/save/'+digitize.layer.id;
    var request = GXmlHttp.create();
    request.open("POST", url, true);
    request.setRequestHeader("Content-Type", "text/xml")
    request.onreadystatechange = function() {
	if (request.readyState==4) {
	// reload index incase changes are reflected there too
	    digitize.reloadIndex();  // incase details in index have changed
	}
    }

    // revisit - could save just changes
    var xml = digitize.layer.getXml();
    //log(xml);
    request.send(xml);
 }

// if select, add, otherwise abort adding
digitize.addPoint = function DigitizeAddPoint(selected)
{
    digitize.setMode('point',selected);
}

digitize.addLine = function DigitizeAddLine(selected)
{
    digitize.setMode('line',selected);
}

digitize.addPolygon = function DigitizeAddPolygon(selected)
{
    digitize.setMode('polygon',selected);
}

//---- point handlers ----

digitize.pointMouseMove = function Digitize_pointMouseMove(point)
{
    //log('move');
    digitize.pointMarker.setPoint(point);
}

digitize.pointMouseOut = function Digitize_pointMouseOut()
{
    //log('out');
    map.removeOverlay(digitize.pointMarker);
}

digitize.pointClick = function Digitize_pointClick(overlay, point)
{
    digitize.setMode('point',false);
    var f = new Feature();
    f.geometry = new Point(point);
    f.geometry.feature = f;  // link back to parent
    digitize.layer.features.push(f);
    digitize.setDirty();
    f.show();
    digitize.layer.schema.resetValue();  // set defaults on this feature
    digitize.layer.schema.getValue(f);
    f.geometry.openInfoWindow(point);
}

//---- line handlers ----

digitize.lineClick = function Digitize_lineClick(overlay, point)
{
    if (!point) {
	log("click on overlay "+overlay);
	return;  // click on overlay?
    }

    // double click is used to end line drawing
    if (isDoubleClick(point)) {
	log('pseudeo double click at '+point);
	return digitize.lineDoubleClick(overlay, point);
    }

    log('lineClick lineMode='+digitize.lineMode);
    if (digitize.mapModeSelected) {
	if (digitize.lineMode==0) {
	    // mode 0: about to draw first point
	    var f = new Feature();
	    var line = new Line();
	    f.geometry = line; // mutual references
	    line.feature = f;
	    digitize.activeLine = line;
	    line.addVertex(point);
	    line.addVertex(point);
	    digitize.layer.features.push(f);
	    digitize.setDirty();
	    f.show();
	    digitize.lineMode=1;
	    digitize.modeListeners.push(GEvent.addListener(map, 'mousemove', digitize.lineMouseMove));
	} else if (digitize.lineMode==1) {
	    // mode 1: extending line with new points
	    digitize.activeLine.addVertex(point);
	    digitize.setDirty();
	}
    } else {
	//dumpObj(overlay);
	overlay.openInfoWindow(point)
    }
}

digitize.lineDoubleClick = function Digitize_lineDoubleClick(overlay, point)
{
    // open info window
    digitize.layer.schema.resetValue();  // set defaults on this feature
    digitize.layer.schema.getValue(digitize.activeLine.feature);  // set initial values from schema
    digitize.activeLine.openInfoWindow(point);

    digitize.setMode('line',false);
}

digitize.lineMouseMove = function Digitize_lineMouseMove(point)
{
    if (digitize.lineMode==1) {
	digitize.activeLine.moveVertex(-1,point);
    }
}

//---- polygon handlers ----

digitize.polygonClick = function Digitize_polygonClick(overlay, point)
{
    if (!point) {
	log("click on overlay "+overlay);
	return;  // click on overlay?
    }

    // double click is used to end line drawing
    if (isDoubleClick(point)) {
	log('pseudeo double click at '+point);
	return digitize.polygonDoubleClick(overlay, point);
    }

    log('polygonClick lineMode='+digitize.lineMode);
    if (digitize.mapModeSelected) {
	if (digitize.lineMode==0) {
	    // mode 0: about to draw first point
	    var f = new Feature();
	    var polygon = new Polygon();
	    f.geometry = polygon; // mutual references
	    polygon.feature = f;
	    digitize.activeLine = polygon;
	    polygon.addVertex(point);
	    polygon.addVertex(point);
	    digitize.layer.features.push(f);
	    digitize.setDirty();
	    f.show();
	    digitize.lineMode=1;
	    digitize.modeListeners.push(GEvent.addListener(map, 'mousemove', digitize.polygonMouseMove));
	} else if (digitize.lineMode==1) {
	    // mode 1: extending polygon with new points
	    digitize.activeLine.addVertex(point);
	    digitize.setDirty();
	}
    } else {
	//dumpObj(overlay);
	overlay.openInfoWindow(point)
    }
}

digitize.polygonDoubleClick = function Digitize_polygonDoubleClick(overlay, point)
{
    // open info window
    digitize.layer.schema.resetValue();  // set defaults on this feature
    digitize.layer.schema.getValue(digitize.activeLine.feature);  // set initial values from schema
    digitize.activeLine.openInfoWindow(point);

    digitize.setMode('polygon',false);
}

digitize.polygonMouseMove = function Digitize_polygonMouseMove(point)
{
    if (digitize.lineMode==1) {
	digitize.activeLine.moveVertex(-1,point);
    }
}

//----
digitize.saveFeature = function Digitize_saveFeature(feature)
{
    // could probably migrate this all to the geometry onSave function closure it is called from
    digitize.layer.schema.getValue(feature);
    //dumpObj(feature);
    feature.setDirty();
    digitize.setDirty();
}

digitize.deleteFeature = function Digitize_deleteFeature(feature)
{
    feature.hide();
    digitize.layer.deleteFeature(feature);
    digitize.setDirty();
}

digitize.loadLayerSchema = function Digitize_loadLayerSchema(callback)
{
    var url = "/xml/load/0";
    var request = GXmlHttp.create();
    request.open("GET", url, true);
    request.onreadystatechange = function() {
	if (request.readyState == 4) {
	    var xml = request.responseText;
	    var dom = GXml.parse(xml);
	    digitize.layerSchema = new Schema();
	    digitize.layerSchema.loadXml(dom.documentElement);
	    var form = digitize.layerSchema.getForm();  // no delete button by default
	    // wrap it in a popup div
	    var div = document.createElement('div');
	    div.className = 'popup';
	    div.appendChild(form);
	    digitize.openLayerDiv = div;
	    document.body.appendChild(div);
	    callback();
	}
    }
    request.send(null);
}

digitize.saveLayerProperties = function Digitize_saveLayerProperties()
{
    digitize.closeLayerProperties();
    digitize.layerSchema.getValue(digitize.layer);
    digitize.loadLayerInfo();
    digitize.saveLayer();
}

digitize.deleteLayer = function Digitize_deleteLayer()
{
    if (confirm("Are you sure you want to delete this layer?")) 
    {
	var div = document.getElementById('layeredit');
	div.style.display = 'none';
	var url = '/xml/delete/'+digitize.layer.id;
	var request = GXmlHttp.create();
	request.open("GET", url, true);
	request.onreadystatechange = function() {
	    if (request.readyState==4) {
		digitize.closeLayer();
		digitize.reloadIndex();
	    }
	}
	request.send(null);
    }
}

/* callbacks triggered from dropdown menu */

digitize.updateActionMenu = function Digitize_updateActionMenu()
{
    var select = document.getElementById('layeredit_action'); // drop down menu
    var publishOption = select.childNodes[3];
    var published = digitize.layer.published=='t';
    if (published) {
	publishOption.value = "unpublishLayer";
	publishOption.firstChild.nodeValue = "unpublish";
    } else {
	publishOption.value = "publishLayer";
	publishOption.firstChild.nodeValue = "publish";
    }
}

digitize.unpublishLayer = function Digitize_unpublishLayer()
{
    if (confirm("Are you sure you want to make this layer very PRIVATE?"))
    {
	digitize.layer.published = 'f';
	digitize.saveLayer();
	digitize.updateActionMenu();
    }
}

digitize.publishLayer = function Digitize_publishLayer()
{
    if (confirm("Are you sure you want to make this layer AVAILABLE TO ALL USERS?")) 
    {
	digitize.layer.published = 't';
	digitize.saveLayer();
	digitize.updateActionMenu();
	reloadUserLayers(1000);  // update list of published user-layers
    }
}

digitize.submitLayer = function Digitize_submitLayer()
{
    if (confirm("Are you sure you want to submit this data to ATGIS for processing?")) 
    {
	var url = '/xml/submit/'+digitize.layer.id;
	var request = GXmlHttp.create();
	request.open("GET", url, true);
	request.onreadystatechange = function() {
	    if (request.readyState==4) {
                alert("This layer has been submitted to ATGIS for processing.");
            }
        }
	request.send(null);
    }
}

digitize.editLayerProperties = function Digitize_editLayerProperties()
{
    if (digitize.layerSchema==null) {
	digitize.loadLayerSchema(digitize.editLayerProperties);  // call me back
	return;
    }
	
    var schema = digitize.layerSchema;
    schema.onSave = function() {
	digitize.saveLayerProperties(this);
    }
    schema.onCancel = function() {
	digitize.closeLayerProperties();
    }
    schema.onDelete = function() {
	digitize.deleteLayer(this);
	digitize.closeLayerProperties();
    }

    // do not let them change the schema
    schema.setReadOnly('schema_id',true);  // must happen before set value
    schema.showDeleteButton(true);
    digitize.layerSchema.setValue(digitize.layer);
    digitize.openLayerDiv.style.display = 'block';
}

digitize.getShapefile = function Digitize_getShapefile()
{
    this.saveLayer();
    document.location.href='/userlayer/'+this.layer.id;
}

digitize.zoomToLayer = function Digitize_zoomToLayer()
{
    if (digitize.layer!=null && digitize.layer.features.length>0) {
	var limit = null;
	for (var i=0;i<digitize.layer.features.length;i++)
	{
	    var bounds = digitize.layer.features[i].geometry.getBoundingBox();
	    if (i==0) 
            {
		limit = bounds;
	    } else {
		limit.extend(bounds.getNorthEast());
		limit.extend(bounds.getSouthWest());
	    }
	}
	map.setCenter(limit.getCenter(), map.getBoundsZoomLevel(limit));
    }
}

digitize.loadGpxSchema = function Digitize_loadGpxSchema(callback)
{
}

digitize.loadGpx = function Digitize_loadGpx()
{
    if (digitize.gpxPopup==null) {
	digitize.gpxPopup = new UploadForm("GPX Upload", '/gpx');
    }
    digitize.gpxPopup.show();
}

    function UploadForm(title, url)
{
    this.title = title;
    this.url = url;
    this.init();
}

UploadForm.prototype.init = function UnloadForm_init()
{
    var me = this;

    var windowDiv = document.createElement('div');
    windowDiv.className = 'xmldialog';

    var titleDiv = document.createElement('div');
    titleDiv.className = "title";
    titleDiv.appendChild(document.createTextNode(this.title));
    windowDiv.appendChild(titleDiv);

    var formDiv = document.createElement('form');
    formDiv.className = "form";
    formDiv.setAttribute('method', 'POST');
    formDiv.setAttribute('action', this.url);
    this.form = formDiv;
    windowDiv.appendChild(formDiv);

    var fileInput = document.createElement('input');
    fileInput.setAttribute('type', 'file');
    fileInput.setAttribute('size', 30);
    fileInput.setAttribute('id','fileToUpload');
    fileInput.setAttribute('name','fileToUpload'); // turns out this must be set for ajaxFileUpload
    formDiv.appendChild(fileInput);

    var infoDiv = document.createElement('div');
    infoDiv.className = 'info';
    infoDiv.appendChild(document.createTextNode('Please complete all required fields'));
    windowDiv.appendChild(infoDiv);
    this.infoDiv = infoDiv;

    var controlDiv = document.createElement('div');
    controlDiv.className = 'control';
    windowDiv.appendChild(controlDiv);

    var saveButton = controlDiv.appendChild(document.createElement('button'));
    saveButton.className = "save";
    saveButton.name = "save";
    saveButton.appendChild(document.createTextNode('Load'));
    saveButton.onclick = function() {me.onSave();};
    controlDiv.appendChild(saveButton);

    var cancelButton = controlDiv.appendChild(document.createElement('button'));
    cancelButton.className = "cancel";
    cancelButton.name = "cancel";
    cancelButton.appendChild(document.createTextNode('Cancel'));
    cancelButton.onclick = function() {me.onCancel();};
    controlDiv.appendChild(cancelButton);

    var busyIcon = controlDiv.appendChild(document.createElement('img'));
    busyIcon.className = "hidden";
    busyIcon.setAttribute('src','/images/busy.gif');
    controlDiv.appendChild(busyIcon);
    this.busyIcon = busyIcon;

    this.popup = document.createElement('div');
    this.popup.className = 'popup';
    this.popup.appendChild(windowDiv);
    document.body.appendChild(this.popup);
}

UploadForm.prototype.onSave = function UploadForm_onSave()
{
    $(this.busyIcon).show();
    $.ajaxFileUpload({
	    url:'/gpx?id='+digitize.layer.id+'&type='+digitize.layer.schema.type,
	    secureuri:false,
	    fileElementId:'fileToUpload',
	    dataType: 'json',
	    success: function(data,status) 
	    {
		$(digitize.gpxPopup.busyIcon).hide();
		if (data.id==0) {
		    alert('Upload failed. '+data.error);
		} else {
		    digitize.gpxPopup.hide();
		    digitize.loadLayerById(digitize.layer.id);
		    alert('Upload succeeded - '+data.message);
		}
	    },
	    error: function(data,status,e)
	    {
		$(digitize.gpxPopup.busyIcon).hide();
		alert('Upload failed.  Invalid server response.');
	    }
	});
}

UploadForm.prototype.onCancel = function UploadForm_onCancel()
{
    this.hide();
}

UploadForm.prototype.show = function UploadForm_show()
{
    $(this.popup).fadeIn('normal');
}

UploadForm.prototype.hide = function UploadForm_hide()
{
    $(this.popup).fadeOut('normal');
}


function reloadUserLayers(delay)
{
    if (delay>0) {
	// if delayed, execute later
	setTimeout(reloadUserLayers, delay);
    } else {
	// otherwise execute now
	$('#userlayers').load('/userlayers');
    }
}