var polyStack=new Array(), lineStack=new Array(), pointStack=new Array();
var sPos=0,sAddr=0;
var block=new Array();
var editmode=0;
var locCount=new Array();
var inputMode=0;
var _s='q';
var _jlog='';
var currentID=0;

function init(){
	block[0]=document.getElementById('question');
	block[1]=document.getElementById('help');
	setModeContent(0);
	locCount[0]=0;
	locCount[1]=0;
	//alert('init');
}

function setEditMode(mode,loading){
	//alert('editMode request '+mode);
	map.getDragObject().setDraggableCursor('pointer');
	
	if(editmode==mode && !loading) return;

	//remove old mode stuff
	var oldmode=Math.abs(editmode);
	var tmp = document.getElementById(_s+oldmode);
	tmp.className='';
	
	switch(oldmode){
	case(0):
	case(1):hideLocations();break;
	case(2):clearData(pointStack,loading);break;
	case(3):clearCircle();break;
	case(4):clearData(lineStack,loading);break;
	case(5):clearData(polyStack,loading);break;
	}
	
	//alert('editMode ok '+mode);
	tmp=document.getElementById(_s+mode);
	tmp.className='mode';
	
	//alert('set:'+mode);
	if(!loading){
		switch(mode){
		case(0):if(sAddr)addPoint(sAddr);break;
		case(1):if(sPos)addPoint(sPos);break;
		case(2):loadData(pointStack);break;
		case(3):loadCircle();break;
		case(4):loadData(lineStack);break;
		case(5):loadData(polyStack);break;
		}
	}
	
	setModeContent(mode);
	editmode=mode;
}

var contentArr=new Array('Address;addr|Zip/Town;zip|Country;country','X:;xpos|Y:;ypos','List of points. The player will have to enter the same amount of points to answer. Can be used for star constellations, or for listing all the McDrives in an area.','Circular area. Allows more error than a simple dot. Anywher whithin the circle an answer is accepted as correct.','Click on the map to draw a line. The player must click close to the line.','Click on the map to draw a polygon. The player must click within the area to answer correctly.');

var log='';

function cr(s,att,d){
	//log+='create:'+s+"\r\n";
	var e=document.createElement(s);
	if(d){
		if(d.length){
			if(d.split){
				//log+='set html:'+d.substring(0,10)+"...\r\n";
				e.innerHTML=d;
			}else{
				for(var i=0;i<d.length;i++){
					//log+='add '+i+'-child:'+d[i].tagName+"\r\n";
					e.appendChild(d[i]);
				}
			}
		}else{
			//log+='add child:'+d.tagName+"\r\n";
			e.appendChild(d);
		}
	}
	if(att){
		for(var i in att){
			//log+='set att:'+i+'->'+att[i]+"\r\n";
			e.setAttribute(i,att[i]);
		}
	}
	return e;
}

function setModeContent(mode){
	//alert('setModeContent start');
	var cont = document.getElementById(_s+'cont');
	//alert('found cont? '+cont);
	//var out=contentArr[mode].replace(/id=\"/g,'id="'+_s);
	var txt = contentArr[mode];
	var tb = cr("tbody");
	
	if(txt.indexOf('|')>0){
		var f=txt.split('|');
		for(var i=0;i<f.length;i++){
			var d=f[i].split(';');
			var id = _s+d[1];
			//log='';
			var row = cr("tr",{},new Array(
				cr('td',{className:'ar'},d[0]),
				cr('td',{},cr('input',{id:id}))
			));
				
			tb.appendChild(row);
			//alert(log);
		}
	}else{
		var td=cr('td',{colspan:2},txt);
		td.className='info';
		var row = cr("tr",{},td);
		tb.appendChild(row);
	}
	if(cont.firstChild) cont.removeChild(cont.firstChild);
	cont.appendChild(tb);
	//alert('setModeContent done');
}

var lcpoint;
function clickListener(overlay, point){
	if(block[inputMode].style.display=='none') setCurrentID(0);
	
	if(lcpoint==point) return;
	lcpoint=point;
	
	switch(editmode){
	case(0):addPoint(point);sAddr=point;break;
	case(1):addPoint(point);sPos=point;break;
	case(2):addPoints(point);break;
	case(3):addCircle(point);break;
	case(4):addLinePoly(point);break;
	case(5):addFillPoly(point);break;
	}
}

var markIcon=null,mm_opt;
function initMarkMarker(){
	markIcon = new GIcon();
	markIcon.image = "/img/dot.png";
	markIcon.iconSize = new GSize(17, 17);
	markIcon.iconAnchor = new GPoint(8, 8);
	mm_opt = { icon:markIcon, draggable:true, bouncy:false };
}

function addMark(point){
	if(!markIcon) initMarkMarker();
	var marker=new GMarker(point,mm_opt);
	map.addOverlay(marker);
	marker.enableDragging();
	return marker;
}

//single point, used for default version
function addPoint(point){
	hideLocations();
	addLocation(point);
	var pts=point.lat()+","+point.lng();	
	geocoder.getLocations(pts,handleResponse);
}

function addPoints(point){
	if(!point) return;
	var marker=addMark(point);
	GEvent.addListener(marker,"click",function(){
		map.removeOverlay(marker);
		removeFromArray(marker,pointStack);
	});
	pointStack.push(marker);
}

var tc;
var circle,circleLine=0;

function loadCircle(){
	if(circleLine){
		map.addOverlay(circleLine);
		map.addOverlay(circle[0]);
		map.addOverlay(circle[1]);
	}else{
		circle=0;
	}
}

function clearCircle(){
	if(circleLine){
		map.removeOverlay(circleLine);
		map.removeOverlay(circle[0]);
		map.removeOverlay(circle[1]);
	}
}

function addCircle(point){
	var marker=addMark(point);
	if(circleLine || !circle){
		if(circleLine){
			map.removeOverlay(circle[0]);
			map.removeOverlay(circle[1]);
			map.removeOverlay(circleLine);
			circleLine=0;
		}
		circle=new Array();
		circle[0]=marker;
	}else{
		circle[1]=marker;
		circleLine = drawCircle(circle[0].getPoint(),circle[1].getPoint());
		GEvent.addListener(circle[0], "dragend", function() {
			map.removeOverlay(circleLine);
			circleLine = drawCircle(circle[0].getPoint(),circle[1].getPoint());
        });
        GEvent.addListener(circle[1], "dragend", function() {
			map.removeOverlay(circleLine);
			circleLine = drawCircle(circle[0].getPoint(),circle[1].getPoint());
        });
	}
}

function loadData(arr){
	for(var i in arr) map.addOverlay(arr[i]);
}

var epoly;

function clearData(arr,clear){
	if(editmode<0 && epoly){
		epoly.disableEditing();
		map.removeOverlay(epoly);
		epoly=null;
	}
	for(var i in arr) map.removeOverlay(arr[i]);
	if(clear) arr.length=0;
}

function timeCheck(txt){
	var c = new Date();
	var s = c.getSeconds();
	var m = c.getMinutes();
	var h = c.getHours();
	var t = h+':'+m+':'+s;
	_jlog+= t+'add('+editmode+')'+"\r\n";
	return t;
}

function addFillPoly(point){ addPoly(GPolygon,polyStack,new Array(point)); }
function addLinePoly(point){ addPoly(GPolyline,lineStack,new Array(point)); }

//var lastTime=0;
function addPoly(GType,stack,point,disable){
	if(editmode<0) return;
	editmode=-editmode;
	
	/*var currentTime = new Date()
	var t=timeCheck('EM:'+editmode);
	if(lastTime==t){ alert('overlap error'); return;}
	lastTime=t;*/
	
	var poly = new GType([],"#00ff00",3,1,"#00ff00",0.5);
	epoly=poly;//editing polygon reference
	map.addOverlay(poly);
	
	for(var i in point)	poly.insertVertex(i,point[i]);
	
	var limit=(GType==GPolygon)?4:2;
  	
	if(!disable) poly.enableDrawing();
	else{
		editmode=Math.abs(editmode);
	}
	editableG(poly,limit,stack);
	
	poly.enableEditing({onEvent: "mouseover"});
  	poly.disableEditing({onEvent: "mouseout"});
  	
  	//GEvent.addListener(poly,"mouseover",function(){ editmode=-Math.abs(editmode);timeCheck('over'); })
  	//GEvent.addListener(poly,"mouseout",function(){ editmode=Math.abs(editmode);timeCheck('out'); })
	GEvent.addListener(poly,"endline", function() {
		//alert(poly.getVertexCount()+'<'+limit);
		//timeCheck('done');
		poly.disableEditing();
		editmode=Math.abs(editmode);
		if(poly.getVertexCount()<limit){
			map.removeOverlay(poly);
			//alert('too little');
			return;
		}
		epoly=null;
		//alert('enough');
		//alert(_jlog);
	});
}

function editableG(poly,limit,stack){
	stack.push(poly);
	GEvent.addListener(poly, "click", function(latlng, index) {
		if(typeof index == "number"){
			if(poly.getVertexCount()>limit){
				poly.deleteVertex(index);
			}else{
				poly.disableEditing();
				map.removeOverlay(poly);
				removeFromArray(poly,stack);
				editmode=Math.abs(editmode);
			}
		}
	});
}


function handleResponse(response){
	//alert(flatten(response,0));
	if(!response) return;
	if (!response || response.Status.code != 200){
		//no country
	}else{
		var place = response.Placemark[0];
		var c=document.getElementById(_s+'country');
		if (c){
			c.value=place.address?place.address:'';	
		}else{
			var x=document.getElementById(_s+'xpos');
			var y=document.getElementById(_s+'ypos');
			var point = response.Placemark[0].Point.coordinates;
			x.value=point[1];
			y.value=point[0];
		}
	}
}

var _list=new Array();
function getList(){
	if(_list[inputMode]) return _list[inputMode];
	_list[inputMode]=document.getElementById(inputMode?'hlist':'qlist');
}

function addToList(location,id){
	getList();
	
	var question=inputMode?
		document.makeform.flagtext.value
		:document.makeform.asktext.value;
	var bq=!!question;
	var qshow=question=question.replace('*','');
	
	var more='';
	if(!inputMode){
		var inform = document.getElementById('answertext').value.replace('*','');
		more+=inform;
	}
	//bonus time, tollerance
	
	location=location.replace('*','');
	
	if(!qshow){
		if(inputMode)
			switch(editmode){
			case(0):qshow='address('+location.replace(/address\(\s*(.*?)\s*\)/g,'$1')+')';break;
			case(1):qshow='coord('+location.replace(/coord\(\s*(.*?)\s*\)/g,'$1')+')'; break;
			case(4):qshow='line';break;
			case(5):qshow='poly';break;
			default:qshow='---'; break;
			}
		else
			switch(editmode){
			case(0):qshow='Where is '+location.replace(/address\(\s*(.*?)\s*\)/g,'$1')+'?';break;
			case(1):qshow='Find coord('+location.replace(/coord\(\s*(.*?)\s*\)/g,'$1')+')!'; break;
			default:qshow='No Question!!'; break;
			}
	}
	
	if(!id || isNaN(id)){
		//alert('loc:'+locCount[inputMode]);
		locCount[inputMode]++;
		id=locCount[inputMode];
	}
	
	//alert(question+'*'+location+'*'+more);
	
	var data='<input type="button" onClick="removeFromList(this.parentNode)" value="X"><input type="text" name="'+_s+'loc'+id+'" value="'+question+'*'+location+'*'+more+'" class="hide">'+"<span onClick=\"setCurrentID("+id+");showData('"+sl(location)+"','"+sl(question)+"','"+sl(more)+"');\">"+qshow+'</span>';
	
	var x=document.getElementById(_s+'loc'+id);
	if(x){
		x.innerHTML=data;
	}else{
		var what='<div class="loc" id="'+_s+'loc'+id+'">'+data+'</div>';
		_list[inputMode].innerHTML+=what;
		setCurrentID(id);
	}
}

function sl(i){
	return i.replace('\'','\\\'');
}

function setCurrentID(id){
	if(inputMode){
		setVis('help',1);
		setVis('newhelp',0);		
	}else{
		setVis('question',1);
		setVis('newquest',0);
	}
	currentID = id;
	if(!id){
		setIDValue(inputMode?'flagtext':'asktext','');
		setEditMode(0,1);
	}
	var tmp=document.getElementById(inputMode?'actionH':'action');
	var s = inputMode?'Help':'Question';
	if(!id){
		tmp.innerHTML='<input type="button" onClick="store()" value="Add '+s+'">';
	}else{
		tmp.innerHTML='<input type="button" onClick="store()" value="New"> <input type="button" onClick="store('+id+')" value="Update '+s+'">'
	}
}

function setIDValue(id,value,force){
	var tmp = document.getElementById(id);
	if(!tmp && !force) return;
	tmp.value=value;
}

function showData(input,question,more){
	
	setIDValue(inputMode?'flagtext':'asktext',question);
	if(!inputMode){
		var tmp=more.split('*');
		setIDValue('answertext',tmp[0],1);
	}

	var regex = /(.*?)\((.*?)\)$/;
	var match = regex.exec(input);
	var x=0,y=0;

	switch(match[1]){
	case('address'):
		setEditMode(0,1);
		var a=match[2].split(',');
		setIDValue(_s+'addr',a[2]?a[2]:'');
		setIDValue(_s+'zip',a[1]?a[1]:'');
		setIDValue(_s+'country',a[0]);
		addLocationA(match[2]);
		break;
	case('coord'):
		setEditMode(1,1);
		var t = match[2].split(',');
		setIDValue(_s+'xpos',t[0]);
		setIDValue(_s+'ypos',t[1]);
		addLocationXY(parseFloat(t[0]),parseFloat(t[1]));
		break;
	case('points'):
		setEditMode(2,1);
		var t = match[2].split(';');
		var c=0;
		for(var i in t){
			if(!t[i]) continue;
			var s = t[i].split(',');
			addPoints(new GPoint(s[0],s[1]));
			c++;
			x+=s[0];
			y+=s[1];
		}
		centerMap(x/c,y/c);
		break;
	case('circle'):
		var t = match[2].split(',');
		setEditMode(3,1);
		addCircle(new GPoint(t[0],t[1]));
		addCircle(new GPoint(t[2],t[3]));
		centerMap(t[0],t[1]);
		break;
	case('line'):
		setEditMode(4,1);
		var result=extractGroups(match[2]);
		var group=result.g;
		for(var i in group) addPoly(GPolyline,lineStack,group[i],1);
		centerMap(result.x,result.y);
		break;
	case('poly'):
		setEditMode(5,1);
		var result=extractGroups(match[2]);
		var group=result.g;
		for(var i in group) addPoly(GPolygon,polyStack,group[i],1);
		centerMap(result.x,result.y);
		break;
	default: alert('type not matched');
	}
}

function extractGroups(input){
	var group = input.split('|');//groups
	var g=new Array();
	var x=0,y=0,c=0;
	for(var i in group){
		if(!group[i]) continue;
		var p=new Array();
		var point = group[i].split(';');
		for(var j in point){
			if(!point[j]) continue;
			var t=point[j].split(',');
			p.push(new GLatLng(t[0],t[1]));
			c++; x+=parseFloat(t[0]); y+=parseFloat(t[1]);
		}
		if(p.length) g.push(p);
	}
	//alert('GROUP:'+g[0]);
	return {g:g,x:x/c,y:y/c};
}

function removeFromList(obj){
	if(!confirm('Really Delete '+obj.childNodes[2].innerHTML+'?')) return;
	var parent = obj.parentNode;
	parent.removeChild(obj);
}

function setVis(id,b){
	var tmp=document.getElementById(id);
	if(!tmp) return;
	tmp.style.display=b?'block':'none';
}

function secure(text){
	return text.replace(/[\<\>\(\)\[\]\*]/g,'');
}

function gotoLoc(a){
	//alert('goto: '+a);
	hideLocations();
	if(a.indexOf('|')>0){
		a=a.split(/[\|\:]/);
		//alert(a+'>'+parseFloat(a[3])+'-'+parseFloat(a[1]));
		addLocationXY(parseFloat(a[1]),parseFloat(a[3]));
	}else{
		a=a.replace(/.*?\((.*?)\)/,'$1');
		//alert('address: '+a);
		addLocationA(a);
	}
}

function store(id){
	//alert('set:'+mode);
	switch(Math.abs(editmode)){
	case(0):storeAddress(id);break;
	case(1):storeXY(id);break;
	case(2):storePoints(id);break;
	case(3):storeCircle(id);break;
	case(4):storeLines(id);break;
	case(5):storePolys(id);break;
	}
}

function noStore(){
	alert('nothing to store');
	return 0;
}

function storeAddress(id){
	var a=secure(document.getElementById(_s+'addr').value);
	var z=secure(document.getElementById(_s+'zip').value);
	var c=secure(document.getElementById(_s+'country').value);
	if(!c) return noStore();
	
	if(z) z=','+z;
	if(a) a=','+a;
	var out = c+z+a;
	//out = out.replace('\'','\\\'');
	addToList('address('+out+')',id);
	gotoLoc(c+z+a);
}

function storeXY(id){
	var x=parseFloat(document.getElementById(_s+'xpos').value);
	var y=parseFloat(document.getElementById(_s+'ypos').value);
	if(isNaN(x)||isNaN(y)) return noStore();
	addToList('coord('+x+','+y+')',id);
}

function storeCircle(id){
	if(!circle || !circle[0] || !circle[1]) return noStore();
	var c=circle[0].getPoint();
	var r=circle[1].getPoint();
	addToList('circle('+c.x+','+c.y+','+r.x+','+r.y+')',id);
}

//var polyStack=new Array(), lineStack=new Array(), pointStack=new Array();
function storePoints(id){
	if(!pointStack.length) return noStore();
	var out='points(';
	for(var i in pointStack){
		var t = pointStack[i].getPoint();
		out+=t.x+','+t.y+';';
	}
	out+=')';
	addToList(out,id);
}

function storeLines(id){
	if(!lineStack.length) return noStore();
	//alert('Store LineSTACK:'+lineStack.length);
	var s='';
	var out='line(';
	for(var i in lineStack){
		var g = lineStack[i];
		for(var j=0;j<g.getVertexCount();j++){
			var p=g.getVertex(j);
			out+=p.lat()+','+p.lng()+';';
			//s+=j+';';
		}
		out+='|';
		//s+=i+'|';
	}
	out+=')';
	//alert(s);
	addToList(out,id);
}

function storePolys(id){
	if(!polyStack.length) return noStore();
	var out='poly(';
	for(var i in polyStack){
		var g = polyStack[i];
		for(var j=0;j<g.getVertexCount();j++){
			var p=g.getVertex(j);
			out+=p.lat()+','+p.lng()+';';
		}
		out+='|';
	}
	out+=')';
	addToList(out,id);
}

function validateEmail(){
	var email = document.getElementById('email').value;
	if(email.length<5) return false;
	var tmp = email.replace(/[^\d\w\_\-\@\.]/,'&');
	if(tmp.indexOf('&')>=0) return false;
	var at = email.indexOf('@');
	var dot = email.lastIndexOf('.');
	if(at<0 || dot<0 || dot<at) return false;
	return true;
}

function save(){
	if(!validateEmail()){
		alert('the given email is invalid');
		return;
	}
	var center=map.getCenter();
	var zoom=map.getZoom().toString();
	
	store(currentID);

	document.forms['makeform'].center.value=center.lat()+'_'+center.lng()+'_'+zoom;
	document.forms['makeform'].submit();
}

function removeFromArray(obj,arr){
	for(var i in arr){
		if(arr[i]==obj){
			arr.splice(i,1);
			return;
		}
	}
}

function repeat(t,c){
	var out='';
	for(var i=0;i<c;i++) out+=t;
	return out;
}

function flatten(obj,level){
	var out="\r\n"+repeat('->',level)+'(';
	for(i in obj){
		if(obj[i].toString().charAt(0)=='['){
			out+=i+':'+flatten(obj[i],level+1);
		}else out+=i+':'+obj[i];
		out+="\r\n";
	}
	return out+')';
}

function setTab(j){
	var arr = new Array('questionWrap','helpWrap');
	var tabs = document.getElementById('tabWrap').childNodes;
	for(var i=0;i<arr.length;i++){
		tabs[i].className=(i==j)?'selected':'';
		var obj = document.getElementById(arr[i]);
		obj.style.display=(i==j)?'inline':'none';
	}
	inputMode=j;
	_s=inputMode?'h':'q';
}

function flap(obj){
	var n = obj.nextSibling;
	if(n.className=='content'){
		if(n.style.display=='none'){
			n.style.display='block';
			obj.innerHTML='&#9660;'+obj.innerHTML.substr(1);
		}else{
			n.style.display='none';
			obj.innerHTML='&#9658;'+obj.innerHTML.substr(1);
		}
	}
}

/*function importData(){
	xmlhttp.open("POST",window.location.protocol+'//'+window.location.hostname+'/data/exportData.php',true);
	xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	
	var name,data;
	var sendString='name='+name+'&data='+data;
	//alert(sendString);
	xmlhttp.send(sendString);//
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4){
        	showHighScore(xmlhttp.responseText);
			resetGame();
        }
    }
}

function exportData(){
	xmlhttp.open("POST",window.location.protocol+'//'+window.location.hostname+'/data/importData.php',true);
	xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	
	var name,data;
	var sendString='name='+name+'&data='+data;
	//alert(sendString);
	xmlhttp.send(sendString);//
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4){
        	showHighScore(xmlhttp.responseText);
			resetGame();
        }
    }
}*/