/*
 * $Id: ajax.js 1047 2009-01-26 09:55:43Z root $
 *
 * AJAX calls are used to submit / retreive data without reloading the page.
 */

// We need to do this for IE <= 6...
if (!window.XMLHttpRequest) {
    window.XMLHttpRequest = function() {

        var types = [
            'MSXML2.XMLHTTP.6.0',
            'MSXML2.XMLHTTP.3.0',
            'Microsoft.XMLHTTP'
        ];

        for (var i = 0; i < types.length; i++) {
            try {
                // Internet Explorer (t/m 6) gebruikt een ActiveX Object
                return new ActiveXObject(types[i]);
            }
            catch(e) {}
        }

        return undefined;
    }
}

function submitAjaxForm(url, formName,target) {
    // WARNING FOR IE: if there is an input element in the form with the name 'id',
    // do not use form.getAttribute('id'), this will return the input element instead of the form's id!
	var obj,targetTag;
	if (!(obj = eId(formName))) { return; }
	if (!(targetTag = eId(target))) { return; }

	getstr="";

	for (i=0; i<obj.elements.length; i++) {

		if (obj.elements[i].name.length > 0 && (obj.elements[i].tagName == "INPUT" || obj.elements[i].tagName == "TEXTAREA")) {

			if (obj.elements[i].type == "checkbox") {
				if (obj.elements[i].checked) {
					getstr += obj.elements[i].name + "=" + encodeURIComponent(obj.elements[i].value) + "&";
				} else {
					getstr += obj.elements[i].name + "=&";
				}
			}
			else if (obj.elements[i].type == "radio") {
				if (obj.elements[i].checked) {
	      			getstr += obj.elements[i].name + "=" + encodeURIComponent(obj.elements[i].value) + "&";
				}
			}
			else  {
   				getstr += obj.elements[i].name + "=" + encodeURIComponent(obj.elements[i].value) + "&";
			}
 		}
		if (obj.elements[i].tagName == "SELECT") {
			var sel = obj.elements[i];
			getstr += sel.name + "=" + (sel.options.length > 0 ? encodeURIComponent(sel.options[sel.selectedIndex].value) : '') + "&";
		}

	}

	var divs = targetTag.getElementsByTagName('ul');
	for (i=divs.length-1; i>=0; i--) {
		if (divs[i].className == "errors") {
			divs[i].parentNode.removeChild(divs[i]);
		}
	}

	var xmlObj = new XMLRequestObject(url,getstr ,updateControl);
	xmlObj.setTarget(target);
	xmlObj.setLoadMethod('replacekids');

	xmlhttpPost(xmlObj);
}

/**
 * Toggle loading class and set wait cursor.
 */
function toggleLoading(className) {
    document.body.style.cursor = (className == 'show' ? 'wait' : '');
    var loadElement = eId('ajaxLoad');

    if (loadElement) { loadElement.className = className; }
}

function setAjaxLocation(location) {
    window.location.href = window.location.href.replace(/#.*/, '') + '#' + location;
}

/**
 * Return the part after the # in the location
 */
function getAjaxLocation() {
    var res = window.location.href.split('#');
    if (res == window.location.href) {
        return false;
    }
    return res[1];
}

function getUrl(url, target, post) {

    var xmlObj = new XMLRequestObject(url,post ,updateControl);
    xmlObj.setTarget(target);
    xmlObj.setLoadMethod('replacekids');
    xmlhttpPost(xmlObj);
}

function UpdateControl() {
	this.executeUpdate = function(xmlObj) {
		var xmlData, doc, div, node;

        if (! (xmlData = xmlObj.getXMLData())) { alert('Invalid response received from server.');}
        var xml = xmlData.documentElement;

        // Enable the line below for debugging purposes
        // if (xml == null) { alert(xmlObj.getData()); }

        var data = xml.firstChild.data;
        doc = document.createElement('div');
        doc.innerHTML = data;

		if (xml.getAttribute('type') == "error") { alert("Er is een fout opgetreden!\nFoutmelding: " + data); return;}

		//target element
		var tar = document.getElementById(xmlObj.getTarget());
		//teller voor childnodes
		var i =0;

		switch(xmlObj.getLoadMethod()) {

			case "replacekids":
				tar.innerHTML = data;
	            this.parseTag(tar, true);
				break;
			case "firstkid":
				for (i=doc.childNodes.length-1;i>=0;i--) {
					node = tar.insertBefore(doc.childNodes[i].cloneNode(true),doc.childNodes[0]);
				}
				break;
			case "lastkid":
				for (i=0;i<doc.childNodes.length;i++) {
					node = tar.appendChild(doc.childNodes[i].cloneNode(true));
				}
				break;
			case "before":
				node = tar.parentNode.insertBefore(doc,tar);
				break;
			default: break;
		}
	};

    this.parseTag = function (doctree,script)  {
        if (! doctree) { return; }
        var node, i;
        var tagName, len = doctree.childNodes.length;

        node = doctree;
        if (node.tagName != null) {
            tagName = node.tagName.toUpperCase();
            // Please be aware that the script tag is not recognized
            // in IE if it is the first element in the HTML code
            if (tagName == "SCRIPT"  && script) {
                eval (node.innerHTML);
                node.parentNode.removeChild(node);
                return;
            }
        }

        for(i=0;i<len;i++) {
            this.parseTag(doctree.childNodes[i], script);
        }
    };
}

function XMLRequestObject(strUrl, strSubmit, updateObj) {
	this.url = strUrl;
	this.submitData = strSubmit;
	this.updateObj = updateObj;
	this.data = "";
    this.xmlData = "";
	this.target = "";
	this.loadMethod = "";

	this.getUrl = function() { return (this.url); };
	this.getSubmitData = function() { return (this.submitData); };
	this.getUpdateObj = function() { return (this.updateObj); };
	this.setData = function(data) { this.data = data; };
	this.getData = function() { return (this.data); };
    this.setXMLData = function(xmlData) { this.xmlData = xmlData; };
    this.getXMLData = function() { return (this.xmlData); };
	this.setTarget = function(target) { return (this.target = target); }
	this.getTarget = function() { return (this.target); }
	this.setLoadMethod = function(method) { this.loadMethod = method; }
	this.getLoadMethod = function () { return (this.loadMethod) ; }
}


function xmlhttpPost(xmlObj) {

	var xmlHttpReq = false;

	// Voor Mozilla, Opera en Safari gebruiken we XMLHttpRequest.
	if (window.XMLHttpRequest) {
	  xmlHttpReq = new XMLHttpRequest();
	}

	// We gebruiken de POST methode om gegevens te versturen.
	// T.o.v. de GET methode is het voordeel hierbij dat je de data
	// niet aan de url hoeft te plakken.
	xmlHttpReq.open('POST', xmlObj.getUrl(), true);
	xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

	// Callback functie die aangeroepen wordt wanneer de status van het HttpRequest object veranderd is.
	xmlHttpReq.onreadystatechange = function() {
		// readyState 4 betekent dat de request compleet is
		if (xmlHttpReq.readyState == 4) {
            toggleLoading('hide');

			if (xmlHttpReq.status == 200) {		// status 200 betekent dat de pagina goed ontvangen is
				xmlObj.setData(xmlHttpReq.responseText);
                xmlObj.setXMLData(xmlHttpReq.responseXML);
				xmlObj.getUpdateObj().executeUpdate(xmlObj);
			}
            else if(xmlHttpReq.status == 401) {
                //Page requested is not viewable, refresh page to show why
                window.location.reload()
            }
			else {
				// Pagina is niet goed ontvangen, response afhandelen;
			}
		}
	}
    toggleLoading('show');
    xmlHttpReq.send(xmlObj.getSubmitData());
}

String.prototype.unescapeXML = function () {
    return this.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');
}
var updateControl = new UpdateControl();/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}();var oPoly, mapPointsForm, map, updateRace = false;
var cropProductCompat = [];

if (! Array.indexOf) {
	/* Internet Explorer does not have a native indexOf function for arrays */
    Array.prototype.indexOf = function(obj) {
        for (var i=0; i < this.length; i++) {
            if (this[i] == obj) {
                return i;
            }
        }
        return -1;
    };
}

cropProductCompat.remove = function(from, to) {
	var rest = this.slice((to || from) + 1 || this.length);
	this.length = from < 0 ? this.length + from : from;
	return this.push.apply(this, rest);
};

$(function()
{
	initLocationFinder();
	initFieldOptionsForm();
	initMapInputForm();

	$('#videoPopup').click(function(e) {
		$('#show_draw_field_video').dialog({
			draggable: false,
			modal: true,
			resizable: false,
			width: 825
		});
		e.preventDefault();
	});
	$('#organisationId').bind('change', refreshAdvisors);
	$('#organisationId').trigger('change');

	map = initMap();
	oPoly = initPolyApi(map);
});

function handleSeasonSelect(season)
{
	var checkbox = $('#season_' + season + ' input.seasonCheckbox');
	var select = $('#season_' + season + ' select.croprace');
	var price = $('#season_' + season + ' span.price');

	if (checkbox.attr('checked')) {
		select.attr('disabled', false);
		price.css('display', 'inline');
	} else {
		select.attr('disabled', true);
		price.css('display', 'none');
	}
}

function initFieldOptionsForm() {

	// field option form
	var elems = document.forms.addFieldForm.elements;

	if (parseFloat(document.forms.addFieldForm.elements['field[size]'].value) > 0){
		$('#fieldSize').html(document.forms.addFieldForm.elements['field[size]'].value);
	}

	$('#submitToLibrary').click(function(e) {
		submitField('Library');
		e.preventDefault();
	});

	$('#submitToCart').click(function(e) {
		submitField('Cart');
		e.preventDefault();
	});

	$('#addFieldForm td.seasonSelect').each(function(){
		var season = $(this).attr('id').replace('season_', '');
		handleSeasonSelect(season);
	});

	$('#addFieldForm td.seasonSelect input.seasonCheckbox').change(function() {
		handleSeasonSelect($(this).val());
		var label = $(this).parents('td.seasonSelect').find('span.select label');
		var select = $(this).parents('td.seasonSelect').find('select.croprace');

		if (select.attr('disabled')) {
			addRemoveProductCropError(label, false);
		} else {
			var val = select.val();
			if (typeof(productCrops) != 'undefined' && (productCrops.length > 0) && (productCrops.indexOf(val) == -1)) {
				addRemoveProductCropError(label, true);
			}
		}
	});

	$('#addFieldForm td.seasonSelect select.croprace').change(function() {
		updateFields();
		var val = parseInt($(this).val());

		if (typeof(productCrops) != 'undefined' && (productCrops.length > 0)
				&& (productCrops.indexOf(val) == -1) && ! $(this).attr('disabled')) {
			var label = $(this).parents('td.seasonSelect').find('span.select label');
			addRemoveProductCropError(label, true);
		} else {
			var label = $(this).parents('td.seasonSelect').find('span.select label');
			addRemoveProductCropError(label, false);
		}
	});
}

function addRemoveProductCropError(label, add)
{
	var index = cropProductCompat.indexOf(label.text());

	if (add) {
		if (index == -1) {
			label.css('color', 'red');
			cropProductCompat.push(label.text());
		}
	} else if (index > -1) {
		label.css('color', '#284E39');
		cropProductCompat.remove(index, index + 1);
	}

	if (cropProductCompat.length) {
		var msg = $('<div class="fieldOptionsMessage"></div>');
		msg.text(productCropMessage);
		$('#fieldOptionsMessages').html(msg);
	} else {
		$('#fieldOptionsMessages').html('');
	}

}

function submitField(where) {

	if ( (where != 'Library') && (where != 'Cart') ) {
		return;
	}

	document.forms.addFieldForm.elements['action'].value = where;
	document.forms.addFieldForm.submit();
}

function initMap()
{
	map = new GMap2(document.getElementById('map'),
			{ size: new GSize(698,426), draggableCursor: 'pointer', draggingCursor: 'pointer' });

	//map.enableScrollWheelZoom();
	map.addControl(new GMapTypeControl());
	map.addControl(new GScaleControl());
	map.addControl(new GLargeMapControl());
	var overviewCtrl = new GOverviewMapControl();
	map.addControl(overviewCtrl);

	GEvent.addListener(map, 'maptypechanged', function(){
		overviewCtrl.setMapType(map.getCurrentMapType());
	});
	GEvent.addListener(map, 'load', initAvailAreaOverlay);

	map.setMapType(G_HYBRID_MAP);

	return map;
}

function initAvailAreaOverlay()
{
	var url = 'TYPE=shape&SEASON=' + season;

	var copyrightColl = new GCopyrightCollection('');
	var tileLayer= new GTileLayer(copyrightColl,1,17, { opacity:0.8 } );

	tileLayer.myBaseURLFunc = function(a,b) {
        var w = ((a.x + a.y) % hosts.length-1)+1;
        var f = hosts[w] + '?' + url;
        return f;
    };

    tileLayer.myMercZoomLevel=1;
    tileLayer.myLayers='totalExtent';

    tileLayer.myFormat='image/gif';
    tileLayer.getTileUrl = CustomGetTileUrl;

	var olLayer = new GTileLayerOverlay(tileLayer);
	olLayer.visible = true;

	map.addOverlay(olLayer);
}

CustomGetTileUrl = function(a,b,c)
{
	if (typeof(window['this.myStyles'])=="undefined") this.myStyles="";
	var lULP = new GPoint(a.x*256,(a.y+1)*256);
	var lLRP = new GPoint((a.x+1)*256,a.y*256);
	var lUL = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lULP,b,c);
	var lLR = G_NORMAL_MAP.getProjection().fromPixelToLatLng(lLRP,b,c);
	// switch between Mercator and DD if merczoomlevel is set
	if (this.myMercZoomLevel!=0 && b < this.myMercZoomLevel) {
    	var lBbox=dd2MercMetersLng(lUL.x)+","+dd2MercMetersLat(lUL.y)+","+dd2MercMetersLng(lLR.x)+","+dd2MercMetersLat(lLR.y);
    	var lSRS="EPSG:54004";
	} else {
    	var lBbox=lUL.x+","+lUL.y+","+lLR.x+","+lLR.y;
    	var lSRS="EPSG:4326";
	}
	var lURL=this.myBaseURLFunc(a,b);
	lURL+="&REQUEST=GetMap";
	lURL+="&SERVICE=WMS";
	lURL+="&VERSION=1.1.1";
	lURL+="&LAYERS="+this.myLayers;
	lURL+="&STYLES="+this.myStyles; lURL+="&FORMAT="+this.myFormat;
//	lURL+="&BGCOLOR=0xFFFFFF";
	lURL+="&TRANSPARENT=TRUE";
	lURL+="&SRS="+lSRS;
	lURL+="&BBOX="+lBbox;
	lURL+="&WIDTH=256";
	lURL+="&HEIGHT=256";
	lURL+="&reaspect=false";
	return lURL;
//	document.write(lURL);
};

function initPolyApi(map)
{
	var baseUri = '/';

	var isShape = (document.forms.addFieldForm.elements['field[isShapefile]'].value == 1);
	var editablePoly = isShape ? false : true;

	var options = {
			markers: {
				showMarkers: editablePoly,
				dragMarkers: true,
				deleteMarkers: true,
				markerIcon: {
					image: baseUri + 'images/icons/gmaps/marker_sq_10.gif',
					height: 10,
					width: 10,
					anchorOffX: 5,
					anchorOffY: 5
				}
			},
			polygon: {
				addPoints: editablePoly,
				fillColor: '#ff0000'
			},
			center: {
				showCenter: editablePoly,
				dragPoly: true,
				centerIcon: {
				 	image: baseUri + 'images/icons/gmaps/move_sq_18.gif',
					height: 18,
					width: 18,
					anchorOffX: 9,
					anchorOffY: 9
				}
			},
			distanceCallback: displayDistance
		};

	oPoly = new PolyApi(map, options);
	if (isShape) {
		map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/nl_ALL/mapfiles/openhand_8_8.cur),default");
		map.getDragObject().setDraggingCursor("url(http://maps.google.com/intl/nl_ALL/mapfiles/closedhand_8_8.cur),default");
		oPoly.disableClicks();
	}


	oPoly.options.updateCallback = updateField;

	var vertices = document.forms['addFieldForm'].elements['field[vertices]'].value;

	if (vertices != '') {
		var polygon = drawField(vertices);
	} else if (eId('location').value.length > 0) {
		findLocation();
	} else {
		if (window.mapscfg == undefined) {
			alert('error in config: mapscfg not defined');
		} else {
			var center = mapscfg.default_center.split(',');
			map.setCenter(new GLatLng(center[0], center[1]), parseInt(mapscfg.default_zoom));
		}
	}

	if (document.forms.addFieldForm.elements['field[price]'].value != '') {
//		eId('priceIndication').innerHTML = document.forms.addFieldForm.elements['field[price]'].value;
	}

	// remove field handler
	pDomApi.addEvent( eId('removeField'), 'click', function () {

		if (oPoly.getPoints().length>0) {
			oPoly.remove();
			updateField(null,0);
			eId('btnImport').getElementsByTagName('span')[0].style.backgroundPosition = '-83px 0';
			eId('btnDraw').getElementsByTagName('span')[0].style.backgroundPosition = '-108px 0';
			eId('btnInput').style.cursor = 'pointer';

			pDomApi.addEvent( 'btnInput',  'mouseover', function () {
				eId('btnInput').getElementsByTagName('span')[0]
				                                     .style.backgroundPosition = '-133px 0';
			});
			pDomApi.addEvent( 'btnInput',  'mouseout', function () {
				eId('btnInput').getElementsByTagName('span')[0]
				                                     .style.backgroundPosition = '-58px 0';
			});

		}

		// from thickbox. sets the onclick event for the formInput button
		$('#btnInput').click(function(){
			  var t = this.title || this.name || null;
			  var a = this.href || this.alt;
			  var g = this.rel || false;
			  tb_show(t,a,g);
			  this.blur();
			  return false;
		});

		oPoly.options.markers.showMarkers = true;
		oPoly.options.center.showCenter = true;
		oPoly.options.polygon.addPoints = true;
		oPoly.enableClicks();

		document.forms.addFieldForm.elements['field[isShapefile]'].value = 0;

		map.getDragObject().setDraggableCursor("pointer");
		map.getDragObject().setDraggingCursor("pointer");

	});

	return oPoly;
}

function drawField(vertices)
{
	eId('fieldSize').innerHTML = document.forms.addFieldForm.elements['field[size]'].value;
	//eId('priceIndication').innerHTML = document.forms.addFieldForm.elements['field[price]'].value;

	var polygon = vertices.split(';');

	for (var i = 0; i < polygon.length; i++) {
		var vertex = polygon[i].split(':');
		oPoly.addPoint(new GLatLng(vertex[0], vertex[1]), false);
	}
	oPoly.redraw(true);
	var bounds = oPoly.polygon.getBounds();
	map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

	return polygon;
}

function initLocationFinder() {

	// location finder
	pDomApi.addEvent(eId('submitLocation'), 'click', function () { findLocation(); } );
	pDomApi.addEvent(eId('location'), 'keydown', function (e) {

		var event = e | window.event;
		keynum = window.event ? e.keyCode : e.which;

		if (keynum == 13) {
			findLocation();
		}
	});

}


function updateField(poly, area) {

	if (area != undefined) {
		var ha = (window.measureConvert && measureConvert.ha) ? measureConvert.ha : 1;
		eId('fieldSize').innerHTML = Math.round(area / ha * 10) / 10;
		document.forms.addFieldForm.elements['field[size]'].value = area;
	}

	vertices = oPoly.getPoints();
	document.forms.addFieldForm.elements['field[vertices]'].value = vertices;

	polygon = document.forms.addFieldForm.elements['field[vertices]'].value.split(';');

	updateFields();
}

function updateFields()
{
	var size  = $('#fieldSizeInput').val();

	var post = {};
	var count = 0;

	// get the selected season
	$('td.seasonSelect input.seasonCheckbox').each(function() {
		if ($(this).attr('checked')) {
			var parent = $(this).parents('.seasonSelect');
			var season = $(this).val();
			var crop = parent.find('select.croprace').val();
			if (crop > 0) {
				post['field[' + season + '][size]'] = size;
				post['field[' + season + '][crop]'] = crop;
				count++;
			} else {
				parent.find('input.priceIndication').val('-');
			}
		}
	});

	if ((size > 0) && (count > 0)) {
		updateFieldInfo(post);
	}
}

function updateFieldInfo(post)
{
	var url = location.protocol + '//' + location.hostname + '/portal/add-field/getCropInfo.cmd/';

	$.ajax({
		type: 'POST',
		url: url,
		data: post,
		success: function(result) {
			for (var season in result) {
				var info = result[season];
					if (info.price > 0) {
						$('#season_' + season + ' input.priceIndication').val(info.price);
					}
			}
		},
		dataType: 'json'
	});
}

function showHideCropSelect(elem, show) {

	while ( (elem.tagName.toUpperCase() != 'TR')) {
		elem = elem.parentNode;
	}
	newClass = (show) ? 'hide' : 'show';
	oldClass = (show) ? 'show' : 'hide';

	pDomApi.setClassName(elem,oldClass,newClass);
}

function findLocation() {

	if (geocoder == undefined) {
		var geocoder = new GClientGeocoder();
	}

	var address = eId('location').value;

	geocoder.getLatLng(

		address,
		function(point) {
			if (!point) {
				alert(address + ' ' + transArr['txt_js_not_found']);
				if (!map.isLoaded()) {
					map.setCenter(new GLatLng(defaultCenter[0], defaultCenter[1]), defaultZoom);
				}
			} else {
				map.setCenter(point, 16);
			}
		}
	);
}

function displayDistance(distance) {
	var m = (window.measureConvert && measureConvert.m) ? 1 / measureConvert.m : 1;
	eId('pointDistance').innerHTML = Math.round(distance * m);
}

/** map input form  functions **/
function initMapInputForm() {

	$('#btnInput').click(function() {
		$('#mapPointsInputForm').dialog({
			draggable: false,
			modal: true,
			resizable: false,
			width: 700
		});
	});

	$('#btnImport').click(function() {
		$('#mapShapefileInputForm').dialog({
			draggable: false,
			modal: true,
			resizable: false,
			width: 400
		});
	});

	pDomApi.addEvent( 'btnImport', 'mouseover', function () {
		eId('btnImport').getElementsByTagName('span')[0].style.backgroundPosition = '-158px 0';
	});
	pDomApi.addEvent( 'btnImport', 'mouseout', function () {
		eId('btnImport').getElementsByTagName('span')[0].style.backgroundPosition = '-83px 0';
	});

	pDomApi.addEvent( 'btnInput',  'mouseover', function () {
		eId('btnInput').getElementsByTagName('span')[0]
		                                     .style.backgroundPosition = '-133px 0';
	});
	pDomApi.addEvent( 'btnInput',  'mouseout', function () {
		eId('btnInput').getElementsByTagName('span')[0]
		                                     .style.backgroundPosition = '-58px 0';
	});

	pDomApi.addEvent('fieldCoordsType','change', convertCoords);
	pDomApi.addEvent('addNewFieldCoords', 'click', addNewCoordinateInput);
	pDomApi.addEvent('plotFieldCoords','click', function(e) {
		plotFieldCoords(e);
	});
}
/** end map input form functions **/


/** Advisor selection functions **/
function refreshAdvisors(e) {
	var organisationId = $(this).attr('value');

	// remove current advisor select box (if exists)
	$('#advisorId').remove();

	if (organisationId in advisors) {
		var select = document.createElement('select');
		$(select).attr('id', 'advisorId').attr('name', 'field[advisor_id]');

		for (var i in advisors[organisationId]) {
			// Add all advisors belonging to selected organisation
			var optionElem = document.createElement('OPTION');
			optionElem.setAttribute('value', i);
			var textElem = document.createTextNode(advisors[organisationId][i]);

			optionElem.appendChild(textElem);
			select.appendChild(optionElem);
		}
		$(this).after(select);
	}
}

/** coordinates input form functions **/
function convertCoords () {

	var newCoordinates = new Array, lat, lng, newCoord;

	var oldCoordsType = eId('currentCoordsType').value;
	var newCoordsType = eId('fieldCoordsType').value;

	var fieldCoords = pDomApi.getElementsByClassName(eId('fieldCoordsTable'),'tr','coordsRow');

	var coordParts = { 0 : 'lat' , 1 : 'lng' };

	var message = '';
	var newCoord;
	for (var i = 0; i < fieldCoords.length; i++) {

		newCoord = new Array();
		for ( j = 0 ; j < 2 ; j++) {
			point = fieldCoords[i].childNodes[j+1].getElementsByTagName('input')[0].value;

			if ( point == '' ) {
				newCoord[j] = '';
				continue;
			}

			coordPart = convertCoordinate(point, coordParts[j], oldCoordsType, newCoordsType);

			if ( coordPart === false ) {
				message += transArr['txt_js_coordinate']
				       + ' ' + (parseInt(i)+1) + ' ' + coordParts[j] + ' '
				       + ': ' + transArr['txt_js_coordinate_not_correct'] + "\n";
				newCoord[j] = point;
			} else {
				newCoord[j] = coordPart;
			}
		}
		newCoordinates[i] = newCoord;
	}

	for (i = 0; i < fieldCoords.length; i++) {
		fieldCoords[i].childNodes[1].getElementsByTagName('input')[0].value = newCoordinates[i][0];
		fieldCoords[i].childNodes[2].getElementsByTagName('input')[0].value = newCoordinates[i][1];
	}

	if ( message != '' ) {
		alert( message );
	}

	eId('currentCoordsType').value = newCoordsType;
}

function convertCoordinate(coord, latlng, oldType, newType) {

	var tempCoord = new Array();
	var errorCoords = new Array();

	tempCoord = validateCoordinate(coord, latlng, oldType);
	if ( tempCoord == null) {
		return false;
	}

	switch (oldType) {
	case '1':
		coordElems = tempCoord.split(' ');
		var sign = (coordElems[0] < 0) ? -1 : 1;
		var res = new Number (sign * parseFloat(coordElems[1] / 60));
		tempCoord = parseInt(coordElems[0]) + parseFloat(res.toPrecision(8));
		break;

	case '2':
		coordElems = tempCoord.split(' ');
		var sign = (coordElems[0] < 0) ? -1 : 1;
		var res  = new Number(sign * (parseInt(coordElems[1])/60 + parseFloat(coordElems[2] / 3600)));
		tempCoord = parseInt(coordElems[0]) + parseFloat(res.toPrecision(8));
		break;
	}

	switch (newType) {
	case '1':
		var absValue = Math.abs(tempCoord);
		var part  = absValue - parseInt(absValue);
		var minutes = new Number(parseFloat(part*60));
		tempCoord = parseInt(tempCoord) + ' ' + minutes.toPrecision(8);
		break;

	case '2':
		var absValue = Math.abs(tempCoord);
		var part  = absValue - parseInt(absValue);
		var minutes = parseInt(part*60);
		var seconds = new Number( (parseFloat(part*60) - minutes) * 60 );
		tempCoord = parseInt(tempCoord) + ' ' + minutes + ' ' + seconds.toPrecision(4);
		break;
	}

	return tempCoord;

}

function deleteCoordinateInput(e) {

	var event = e || window.event;
	var target = event.target ? event.target : event.srcElement;

	pDomApi.removeEvent(target, 'click', deleteCoordinateInput);

	var parent = target.parentNode;
	while ( parent.className != 'coordsRow' ) {
		parent = parent.parentNode;
	}

	parent.parentNode.removeChild(parent);

	var indexCells = pDomApi.getElementsByClassName(eId('fieldCoordsTable'), 'td', 'key');

	var index = 1;
	for (var i = 0; i < indexCells.length; i++) {
		indexCells[i].innerHTML = index;
		index++;
	}

}

function addNewCoordinateInput() {

	var inputRows = pDomApi.getElementsByClassName(eId('fieldCoordsTable'),'tr','coordsRow');

	var lastInputElems = inputRows[inputRows.length-1].getElementsByTagName('input');

	if ((lastInputElems[0].value == '') || (lastInputElems[1].value == '')) {
		alert(transArr['txt_js_lastrow_not_complete']);
		return;
	}

	var row = inputRows.length + 1;
	var inputRow = document.createElement('tr');
	inputRow.className = 'coordsRow';

	var numberCell = document.createElement('td');
	numberCell.className = 'key';
	var numberCellTxt  = document.createTextNode( row );
	numberCell.appendChild(numberCellTxt);

	var latCell 	= document.createElement('td');
	var latCellTxt 	= document.createTextNode( 'Lat: ' );
	var latInput 	= document.createElement('input');
	latInput.type		= 'text';
	latInput.className 	= 'coordInput';
	latInput.name 		= 'lat[' + row + ']';

	latCell.appendChild(latCellTxt);
	latCell.appendChild(latInput);

	var lngCell 	= document.createElement('td');
	var lngCellTxt 	= document.createTextNode( 'Lng: ' );
	var lngInput 	= document.createElement('input');
	lngInput.type		= 'text';
	lngInput.className 	= 'coordInput';
	lngInput.name 		= 'lng[' + row + ']';
	var deleteLink  = document.createElement('a');
	deleteLink.className = 'deleteCoord';
	deleteLink.href = 'javascript://';
	pDomApi.addEvent(deleteLink, 'click', deleteCoordinateInput);
	var delLnkTxt = document.createTextNode( ' x' );
	deleteLink.appendChild(delLnkTxt);

	lngCell.appendChild(lngCellTxt);
	lngCell.appendChild(lngInput);
	lngCell.appendChild(deleteLink);

	inputRow.appendChild(numberCell);
	inputRow.appendChild(latCell);
	inputRow.appendChild(lngCell);

	eId('fieldCoordsTable').getElementsByTagName('tbody')[0].appendChild(inputRow);

	eId('fieldCoordsTableContainer').scrollTop = eId('fieldCoordsTableContainer').scrollHeight;
	inputRow.getElementsByTagName('input')[0].focus();

}

function validateCoordinate(tmpCoord, latlng, type) {

	var coordTypes = [ 	/^-?\d{1,3}(\.\d+)?$/,
						/^-?\d{1,3} \d{1,2}(\.\d+)?$/,
						/^-?\d{1,3} \d{1,2} \d+(\.\d+)?$/ ];

	tmpPoint = tmpCoord.match(coordTypes[type]);

	if (tmpPoint == null) {
		return null;
	} else {
		pointParts = tmpPoint[0].split(' ');
		if ((latlng == 'lng' && pointParts[0] > -180 && pointParts[0] < 180)
			|| (latlng == 'lat' && pointParts[0] > -90 && pointParts[0] < 90)
		) {
			return tmpPoint[0];
		} else {
			return null;
		}
	}
}

function plotFieldCoords() {

	var coords = new Array;
	var fieldCoords = pDomApi.getElementsByClassName(eId('fieldCoordsTable'),'tr','coordsRow');
	var oldCoordsType = eId('currentCoordsType').value;

	var coordParts = { 0 : 'lat' , 1 : 'lng' };

	for (var i = 0; i < fieldCoords.length; i++) {

		var newCoord = new Array();
		for ( var j = 0; j < 2; j++ ) {
			point = fieldCoords[i].childNodes[j+1].getElementsByTagName('input')[0].value;

			if ( point == '' ) {
				alert( transArr['txt_js_abort_on_coordinate'] + ' ' + (parseInt(i)+1)
						+ ' (' + coordParts[j] + ')' );
				return;
			}

			newCoord[j] = convertCoordinate(point, coordParts[j], oldCoordsType, 0);

			if ( newCoord[j] === false ) {
				alert( transArr['txt_js_abort_on_coordinate'] + ' ' + (parseInt(i)+1)
						+ ' (' + coordParts[j] + ')' );
				return;
			} else {
				coords[i] = newCoord;
			}
		}
	}

	if (oPoly.getPoints().length > 0) {
		oPoly.remove();
	}

	for (i = 0; i < coords.length; i++) {
		vertex = coords[i];
		oPoly.addPoint(new GLatLng(vertex[0], vertex[1]), false);
	}
	oPoly.redraw(true);
	map.setCenter(oPoly.polygon.getBounds().getCenter(), 16);

	eId('mapPointsInputForm').className = 'hide';

	var extraCoords = pDomApi.getElementsByClassName(eId('fieldCoordsTable'), 'a', 'deleteCoord');
	for (var i = 0; i < extraCoords.length; i++) {
		elem = { target: extraCoords[i] };
		deleteCoordinateInput(elem);
	}

	var fieldCoords = pDomApi.getElementsByClassName(eId('fieldCoordsTable'),'tr','coordsRow');

	for (i = 0; i < fieldCoords.length; i++) {

		fieldCoords[i].childNodes[1].getElementsByTagName('input')[0].value = '';
		fieldCoords[i].childNodes[2].getElementsByTagName('input')[0].value = '';
	}
	$('#mapShapefileInputForm').dialog('close');

}
/** end coordinates input form functions **/

/** Shapefile upload form functions **/
function plotShapefile(shape) {

	if (oPoly.getPoints().length > 0) {
		oPoly.remove();
	}

	oPoly.options.markers.showMarkers = false;
	oPoly.options.center.showCenter = false;
	oPoly.options.polygon.addPoints = false;
	oPoly.disableClicks();

	for (var i = 0; i < shape.points.length; i++) {
		vertex = shape.points[i];
		oPoly.addPoint(new GLatLng(vertex[1], vertex[0]), false, false);
	}

	oPoly.redraw(true);
	var center = oPoly.polygon.getBounds().getCenter();
	map.setCenter(center, 16);

	map.getDragObject().setDraggableCursor("url(http://maps.google.com/intl/nl_ALL/mapfiles/openhand_8_8.cur),default");
	map.getDragObject().setDraggingCursor("url(http://maps.google.com/intl/nl_ALL/mapfiles/closedhand_8_8.cur),default");

	eId('mapShapefileInputForm').className = 'hide';
	eId('btnDraw').getElementsByTagName('span')[0].style.backgroundPosition = '-33px 0';
	eId('btnDraw').style.cursor = 'default';

	// recreate the input button
	var btnText = eId('btnInput').childNodes[1].data;
	var href = (eId('btnInput').location == undefined )
				? eId('btnInput').href : eId('btnInput').location.href;
	var btn = document.createElement('a');
	var span = document.createElement('span');
	var text = document.createTextNode(btnText + ' ');
	btn.href= href;
	btn.style.cursor = 'default';
	span.className = 'toolImg';
	btn.appendChild(span);
	btn.appendChild(text);
	var parent = eId('btnInput').parentNode;
	parent.removeChild(eId('btnInput'));
	btn.id = 'btnInput';
	parent.appendChild(btn);

	// set the form shapefile input to true
	document.forms.addFieldForm.elements['field[isShapefile]'].value = 1;
	$('#mapShapefileInputForm').dialog('close');

}
/** end of shapefile upload form functions **//**
 * PolyApi Class.
 * Provides a tool to draw/load shapes on the map and show markers at cornerpoints
 * Ability to drag markers or complete poly as a whole. Surface is calculated on the fly.
 *
 * Use method getPoints to get a string containing the polygon definition.
 *
 * Custom marker images should be placed in:
 * /images/icons/gmaps/
 *
 * Example use:
 *
 *
 * var myPoints	= [{"lat":"51.639060974","lng":"5.224471092"},{"lat":"51.637851715","lng":"5.224428177"},{"lat":"51.637691498","lng":"5.226337910"},{"lat":"51.638927460","lng":"5.226445198"}];
 * var oMap		= new GMap2(document.getElementById("map"),{});
 * oMap.setCenter(new GLatLng(51.639060974,5.224471092), 16);
 *
 * var options = {
 *		markers: {
 *	    	showMarkers: true,
 *	    	dragMarkers: true
 *	    },
 *	    polygon: {
 *	    	addPoints: true,
 *	    	fillColor: '#ff0000'
 *	    },
 *	    center: {
 *	    	showCenter: true,
 *	    	dragPoly: true
 *	    }
 * }
 *
 * var oPoly = new PolyApi(oMap, options);
 * for(i in myPoints) {
 * 		oPoly.addPoint(new GLatLng(myPoints[i]['lat'], myPoints[i]['lng']));
 * }
 *
 *
 * @author		Steven Attevelt <steven@prezent.nl>
 */


/**
 * PolyApi constuctor. Instanciates PolyApi.
 *
 * @param	map		GMap2 	Instance of google maps
 * @param	options literal	JSON notation of options. See this constructor for complete list.
 */
function PolyApi(map, options) {
	this.centerM		=	null;
	this.centerP		=	null;
	this.markers		=	new	Array();
	this.map			=	map;
	this.points			=	new	Array();
	this.polygon		=	null;
	this.mapClickEvt	=	null;
	this.polyClickEvt	=	null;
	this.lastPoint		= 	null;

	this.options	=	{
		markers: {
			showMarkers:	false,
			dragMarkers:	false,
			deleteMarkers:	false,
			markerIcon:	{
				image:	 	'', //  Absolute Url to image
				height: 	10,	// height of image
				width: 		10,	// width of image
				anchorOffX:	5,	// X offset of point to anchor the marker to (usually center)
				anchorOffY:	5	// Y offset of point to anchor the marker to (usually center)
			}
		},
		center: {
			showCenter:		false,	// Show center
			dragPoly:		false,	// Enable dragging poly. if true, showCenter MUSt be true aswell to work
			centerIcon: {
				image:		'',
				height: 	18,
				width: 		18,
				anchorOffX:	9,
				anchorOffY:	9
			}
		},
		polygon: {
			addPoints:		false,			// Allow user to add points. Points can still be added via script.
			lineColor:		'#0000af',
			lineWeight:		3,
			lineOpacity:	.5,
			fillColor:		'#0000af',
			fillOpacity:	.2,
			zPriority:		1
		},
		areaElemId:		'area',	// Id of DOM element in which to display poly surface.
		updateCallback: null,
		distanceCallback: function() {}		
	};
	
	if (options) {
		this.options = this._loadOptions(this.options, options);
	}

	if (this.options.polygon.addPoints) {
		var me = this;
		this.mapClickEvt = GEvent.addListener(this.map, "click", function(overlay, point, overlaypoint)	{
			if (point) {
			 	me.addPoint(point, true);
			 	me.redraw(true);
			}
		});
		
		if (this.options.distanceCallback != null) {
			var me = this;
			GEvent.addListener(this.map, "mousemove", function(point) {
				if (me.lastPoint != null) {
					var distance = point.distanceFrom(me.lastPoint);
					me.options.distanceCallback(distance);
				}
			});
		}		
	}
}


/**
 * Add a point to the polyline. If markers are enabled, a marker is added aswell.
 *
 * @param	overlay	GOverlay	Google overlay object.
 * @param	point	GLatLong	point	defined	in lat/lng
 */
PolyApi.prototype.addPoint = function(point, triggerCallback) {
	if (this.polygon)	{
		this.map.removeOverlay(this.polygon);
	}
	if (triggerCallback !== true) {
		triggerCallback = false;
	}

	// Options may say it is off, we still need the markers for dragging the whole poly.
	this._addMarker(point);

	this.points.push(point);
}

/**
 * Redraw	polygon	and, if	set	in options,	centerpoint	aswell.
 * Shoulnd't need to be called manually as far as i can tell.
 *
 * @param	bool	callUpdateCallback	Wether or not to call a passed updatecallback.
 */
PolyApi.prototype.redraw = function(callUpdateCallback)	{

	if (this.polygon !=	null)	{
		if ( this.polyClickEvt != null ) {
			GEvent.removeListener( this.polyClickEvt );
			this.polyClickEvt = null;
		}
		this.map.removeOverlay(this.polygon);
		this.polygon = null;
	}

	if (this.points.length == 0) {
		this.centerM	=	null;
		this.centerP	=	null;
		return;
	}
	// Fix to draw a closed shape, instead of one vertex missing.

	var fixPoints = new Array();
	var mem				= false;
	for (var i = 0; i < this.points.length; i++) {
		fixPoints.push(this.points[i]);
		if (mem === false) {
			mem = i;
		}
	}
	this.lastPoint = this.points[i-1];
	fixPoints.push(this.points[mem]);

	// Create polygon and add to map
	var polyOpt = this.options.polygon;
	this.polygon	=	new	GPolygon(fixPoints,	polyOpt.lineColor, polyOpt.lineWeight, polyOpt.lineOpacity,	polyOpt.fillColor, polyOpt.fillOpacity);
	this.map.addOverlay(this.polygon);

	// Set click event on poly to allow adding points
	var me = this;
	if ( this.options.polygon.addPoints && (this.polyClickEvt == null)) {

		this.polyClickEvt = GEvent.addListener(this.polygon, "click", function(point)	{
			me.addPoint(point, true);
			me.redraw(true);
		});
	}

	// Draw centerpoint
	if (this.options.center.showCenter) {
		this._redrawCenter();
	}

	// Save this position as default in the map
	this.map.savePosition();
	
	//Display area
	if (this.options.areaElemId != '') {
		var areaElem	= document.getElementById(this.options.areaElemId);
		if (areaElem) {
			areaElem.innerHTML = this.getArea();
		}
	}

	if (this.options.updateCallback != null && callUpdateCallback === true) {
		this._callUpdateCallback();
	}
}
/**
 * Get the points that define the polygon in lat lng. Format of string:
 *
 * lat:lng;lat:lng; etc.
 *
 * @return	string	all coords that define the polygon.
 */

PolyApi.prototype.getPoints = function() {
	var pointStr = '';
	for (i = 0; i < this.points.length; i++) {
		pointStr += ((i > 0) ? ';' : '')
						+ this.points[i].lat() + ':' + this.points[i].lng();
	}
	return pointStr;
}

/**
 * Remove the displayed polygon, markers and center.
 */
PolyApi.prototype.remove = function(disableClicks) {
	// Unset points
	this.points = new Array();
	this.lastPoint = null;

	// Remove markers from map
	for(i = 0; i < this.markers.length; i++) {
		this.map.removeOverlay(this.markers[i]);
	}
	this.markers = new Array();

	// Remove center point
	if (this.options.center.showCenter && ( this.centerM != null )) {
		this.map.removeOverlay(this.centerM);
		this.centerM = null;
		this.centerP = null;
	}

	if (disableClicks && this.mapClickEvt != null) {
		GEvent.removeListener(this.mapClickEvt);
	}

	this.redraw(true);
}

PolyApi.prototype.disableClicks = function() {
	if (this.mapClickEvt != null) {
		GEvent.removeListener(this.mapClickEvt);
		this.mapClickEvt = null;
	}
	if (this.polyClickEvt != null) {
		GEvent.removeListener(this.polyClickEvt);
		this.polyClickEvt = null;
	}
}

PolyApi.prototype.enableClicks = function() {

	if (this.options.polygon.addPoints && (this.mapClickEvt == null)) {
		var me = this;
		this.mapClickEvt = GEvent.addListener(this.map, "click",
									function(overlay, point, overlaypoint)	{
			if (point) {
			 	me.addPoint(point, true);
			 	me.redraw(true);
			}
		});
	}
}

PolyApi.prototype.getArea = function() {
	if (this.polygon != null) {
		return Math.round(this.polygon.getArea()/(1000))/10;
	}
}

/* Non public methods */


PolyApi.prototype._dragCenter = function(newPoint, center) {
	// Get latlng delta
	var latDelta	= this.centerP.lat() - newPoint.lat();
	var lngDelta	= this.centerP.lng() - newPoint.lng();

	// Move all markers and redefine this.points
	this.points = new Array();
	for (i = 0; i < this.markers.length; i++) {
		var m = this.markers[i];
		var mp = new GLatLng(m.getLatLng().lat() - latDelta, m.getLatLng().lng() - lngDelta);
		this.markers[i].setLatLng(mp);
		this.points.push(mp);
	}

	this.centerP = newPoint;
	this.redraw();
}

PolyApi.prototype._redrawCenter = function() {
	if (this.points.length <= 1) {
		if (this.centerM) {
			this.map.removeOverlay(this.centerM);
			this.centerM = null;
			this.centerP = null;
		}
		return;
	}
	var point = this.polygon.getBounds().getCenter();

	if (this.centerM) {

		this.centerM.setLatLng(point);
		this.centerP = point;
	} else {
		if (this.options.center.centerIcon.image !=	'')	{
			var icon = this._createIcon(this.options.center.centerIcon);
		}	else {
			var icon = new GIcon(G_DEFAULT_ICON);
		}

		this.centerP = point;
		this.centerM = new GMarker(point, {icon:icon, draggable:this.options.center.dragPoly, bouncy:false,	dragCrossMove:true});

		if(this.options.center.dragPoly) {
			var	me = this;
			// Drag	listener
			GEvent.addListener(this.centerM, "drag", function(newPoint)	{
				me._dragCenter(newPoint, this.centerM);
			});
			// Drag end to call updateCallback
			if (this.options.updateCallback) {
				GEvent.addListener(this.centerM, "dragend", function(point) {
					me.redraw(true);
				});
			}
		}
		this.map.addOverlay(this.centerM);
	}
}

PolyApi.prototype._addMarker = function(point) {
	if (this.options.markers.markerIcon.image != '')	{
		 var icon	=	this._createIcon(this.options.markers.markerIcon);
	}	else {
		 var icon	=	null;
	}
	var	marker = new GMarker(point,	{icon:icon,	draggable:this.options.markers.dragMarkers,	hide: !this.options.markers.showMarkers, bouncy:false,	dragCrossMove:true});

	this.map.addOverlay(marker);

	var	me = this;
	if (this.options.markers.dragMarkers)	{
		// Drag	listener
		GEvent.addListener(marker, "drag", function(newPoint)	{
			me._dragMarker(newPoint, marker);
		});
	}
	if (this.options.markers.deleteMarkers)	{
		// delete	listener
		GEvent.addListener(marker, "click", function(point)	{
			me._deleteMarker(marker);
		});
	}
	if (this.options.updateCallback != null) {
		// At end of drag, call updatCallback
		GEvent.addListener(marker, "dragend", function(point) {
			me.redraw(true);
		});
	}

	this.markers.push(marker);
}

PolyApi.prototype._deleteMarker = function(marker) {
	var newMarkers	= new Array();
	var newPoints	= new Array();

	// Finde marker to delete, else place in new array
	for (i = 0; i < this.markers.length; i++) {
		if (this.markers[i] == marker) {
			var point = marker.getLatLng();
			this.map.removeOverlay(marker);
		} else {
			newMarkers.push(this.markers[i]);
			newPoints.push(this.markers[i].getLatLng());
		}
	}
	// Use new arrays for points and markers.
	this.points = newPoints;
	this.markers = newMarkers;
	this.redraw(true);
}

PolyApi.prototype._dragMarker = function(newPoint, marker) {
	// Change	update points based on markers.
	this.points	=	new	Array();
	for	(i = 0; i < this.markers.length; i++)	{
		this.points.push(this.markers[i].getLatLng());
	}
	this.redraw();
}

PolyApi.prototype._callUpdateCallback = function() {
	if (this.options.updateCallback != null) {
		var area = this.getArea();
		var poly = this.getPoints();

		this.options.updateCallback(poly, area);
	}
}

/**
 * Create	an icon	object *
 */
PolyApi.prototype._createIcon	=	function(iconOpt) { //	Add	icon attributes
	var	icon			= new GIcon();
	icon.image			= iconOpt.image;
	icon.iconSize		= new GSize(iconOpt.width, iconOpt.height);
	icon.iconAnchor		= new GPoint(iconOpt.anchorOffX, iconOpt.anchorOffY);
	icon.dragCrossImage	= '';
	icon.dragCrossSize	= new GSize(0,0);
	icon.maxHeight		= 0;
	return icon;
}

PolyApi.prototype._loadOptions = function(stdOption, newOption) {
	
	for (option in newOption) {
		if ( typeof(stdOption[option]) == 'object' ) {
			stdOption[option] = this._loadOptions(stdOption[option], newOption[option]);

		} else if ( typeof(stdOption[option]) != 'undefined') {
			stdOption[option] = newOption[option];
		}
	}
	return stdOption;
}

