/*
Core Javascript framework, version 500\Helmwind
*/

function Show(s){
	var items = $w(s);
	items.each(function(t){$(t).show();});
}

function Hide(s){
	var items = $w(s);
	items.each(function(t){$(t).hide();});
}

function Blank(s){
	var items = $w(s);
	items.each(function(t){$(t).reset();});
}

var DevelopNotice = {
	fatal:function(r){
		//alert(r);
	},
	debug:function(r){
		//alert(r);
	}
}


var Core = {
	version:500,
	custom:true,
	debug:false,
	enable_escape_key:false,
	last_key_pressed:-1,
	init:function(){
		Server.use_disconnected_mode=false;//sets this up as faking a server back end
		Server.init();
		
		//page-level optional custom function
		try{__init();}catch(ex){}
		try{Page.init();}catch(ex){}
	},
	//for things that can only run at the very last part of the page
	__post_load:null,
	preload_images:function(imgs){
		$A(imgs).each(function(img){
			preload_image = new Image(25,25); 
			preload_image.src=img;
		});
	},
	//whenever the user presses the escape key the most recent item pushed onto Core will be fired.
	add_escape_callback:function(c){
		if(!Core.enable_escape_key) return;
		this.escape_key_callbacks.push(c);
	},
	escape_key_callbacks:$A([]),
	on_escape:function(){
		if(!Core.enable_escape_key) return;
		if(this.escape_key_callbacks.length > 0){
			var callback = this.escape_key_callbacks.pop();
			callback();
		}
	}
}

//fakes a global last key variable to mask browser differences and ff's requirement of an event obj as a param
Event.observe(window, 'keydown', function(e){
	try{
		e = window.event ? event : e;
		lastKeyPressed = e.keyCode ? e.keyCode : e.charCode;
		Core.last_key_pressed = lastKeyPressed;
	}catch(ex){
		//for ie
	}
	if(Core.last_key_pressed==27){
		Core.on_escape();
	}
});

function onenter(cbk){
	try{
		var e = window.event ? event : e;
		lastKeyPressed = e.keyCode ? e.keyCode : e.charCode;
		if(lastKeyPressed==13 || lastKeyPressed==3) cbk();
	}catch(ex){
		//firefox does not work because it has no window.event property, and there is no way to pass the event object here as this method is called from
		//onkeypress="onenter(Obj.func)". so firefox users will not be able to press enter. it's silly to make long complex js calls to wire these up,
		//so we fake a window.event object for firefox at some point i guess
		if(Core.last_key_pressed==13 || Core.last_key_pressed==3) cbk();
	}
}


//all initialization is done through this, although since Event.observe can take a lot of args it probably doesn't matter
//no as we want the xmlhttp to work even if the page isnt loaded fully
// Event.observe(window, 'load', Core.init);


//importing of other files
//document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');



function getinfo(r){
	return Object.keys(r).collect(function(y){return y+':\n'+r[y];}).join('\n')
}


function Find(args){
	var a = {};
	args = $A(args);
	
	args.each(function(pv){
		var prefix = pv[0];
		var str = pv[1];
		$w(str).each(function(t){
			if($(prefix+t) != null){
				a[t] = $F(prefix+t);
			}
		});
	});
	
	return a;
}


/*
sample use:
Request('do-something -f', {arg1:true,arg2:false}, function(r){
	//do work
});

also feel free to leave the last param, the callback function, blank if you don't care to do anything on the server's action
*/

function FakeRequest(a,b,c){c({ok:true,msg:'this is a fake message',html:'this is fake html'})};

function Request(str, obj, cbk){
	
	if(cbk==undefined || cbk==null) cbk=function(){};//could wire up to a debug handler if needed
	
	str=str.split(' ');
	
	//command line options separated by spaces are pre-processed here
	Server.server_post_target = str[0];
	if(str.length>1){
		if(str[1]=='-f'){
			Server.send_form_data_by_default = true;
		}else{
			Server.send_form_data_by_default = false;
		}
	}
	
	//.net jsondata lib chokes on null, undefined, or empty objects
	if(obj==null || obj==undefined || Object.keys(obj).length==0){
		obj = {empty:true};
	}
	
	//send it
	Server.send(obj, cbk);
	
}


//do not call this directly
//instead, use the Request function defined above.
var Server = {
	use_disconnected_mode:false,/*for testing this without a server-side framework*/
	server_post_target:-1,//if this is -1 then we should just print the request to the last request area
	send_form_data_by_default:false,
	
  object_to_h:function(obj){
    var str='';
    Object.keys(obj).each(function(k){
      str += '<strong>'+k.toString()+'</strong><em>'+obj[k.toString()]+'</em>';
    });
    return str;
  },
  
  //debug tool
  alert_all_items:function(r){
    alert(Object.keys(r).collect(function(y){return y+':\n'+r[y];}).join('\n'));
  },
  
  //the main entry point
  send:function(o,cbk){
	
    if(this.server_post_target==-1){
      //debug mode, don't send to server
      DevelopNotice.debug(this.object_to_h(o));
      return;//don't process
    }
    
	  var sendformdata = this.send_form_data_by_default;//delta later from args if you want
	  var obj_for_server = o;
	  
	  if(sendformdata){
			var formdata = Server.collect_all_form_data();
			Object.keys(formdata).collect(function(y){obj_for_server[y]=formdata[y];});
	  }
	  
	  this.queueup(this.server_post_target, obj_for_server, function(r){
      var obj;
      try{
        obj = eval('('+r+')');
				
				if(obj['site_offline'] != undefined && obj['site_offline'] != null && obj['site_offline'] == true){
					//maintenance mode
					window.open('/upgrades.html', '_self');
				}else{
					try{
						cbk(obj);
					}catch(ex){
						DevelopNotice.fatal("Your custom callback threw an error: " + ex.toString());
					}
				}
      }catch(ex){
        DevelopNotice.fatal('The server\'s response could not be parsed as JSON' + '\n' + r + '\n\n\n'+ex.message);
      }
	  });
	  
	  //note that the cmd will not be available as a part of the _page_state_ as soon as the request is sent. so we put it here
	  this.last_cmd = o;
	  this.last_formdata = formdata;
	},
	
	////////////////////////////////////////////////////////////////////////////////////////////////
	//internals below
	//persistent_data:{},//holds the last object passed to the server. probably not very useful, so i removed it
	last_cmd:null,
	last_formdata:null,
	
	//xmlhttp object
	xh:false,
	//queue for requests
	queue_being_processed:false,
	/*
	var: xhreq_queue
	Holds XmlHttp requests before they are sent
	*/
	xhreq_queue:[],
	/*
	func: queueup
	Calls send using an object--turns the object into post data. Sends a request to the specified handler with the specified arguments and attached the passed function as the callback
	*/
	queueup:function(handlerpath, argobj, on_request_complete){
		//& in json must be escaped, as must ;, otherwise the server breaks
		this.send_underlying(handlerpath, "obj=" + Object.toJSON(argobj).gsub('&', '%26').gsub(';', '%3B'), on_request_complete);	
	},
	/*
	func: send
	Sends a request to the specified handler with the specified arguments and attached the passed function as the callback. Uses a queue to make sure these async calls don't back up (which they will in FireFox without a queue).

	Remarks:
	send the args to the handlerpath, and add the appropriate folder if it's not part of the handler path

	*/
	send_underlying:function(handlerpath, argstring, on_request_complete){
		
		this.add_to_queue(handlerpath, argstring, on_request_complete);
		
	},
	/* func: add_to_queue
	Adds XmlHttp requests to a queue (<xhreq_queue>) because FireFox will throw errors if you send too many at once.
	*/
	add_to_queue:function(handlerpath, argstring, on_request_complete){
		this.xhreq_queue = $A(this.xhreq_queue);
		this.xhreq_queue[this.xhreq_queue.length] = {'handlerpath':handlerpath, 'argstring':argstring, 'on_request_complete':on_request_complete};
	    
		if(!this.queue_being_processed){
			this.queue_being_processed = true;
	        
			//process it
			this.process_xh_queue();
		}
	},
	/*
	func: process_xh_queue
	Processes queued requests to the server
	*/
	process_xh_queue:function(){
	    
		//Error.notify(xhreq_queue.inspect());
	    
		if(this.xhreq_queue.length > 0){
			var reqitem = this.xhreq_queue[0];
			this.sendtoserver(reqitem.handlerpath, reqitem.argstring, reqitem.on_request_complete, function(){
				Server.xhreq_queue = Server.xhreq_queue.without(reqitem);
				Server.process_xh_queue();
			});
		}else{
			this.queue_being_processed = false;
		}
	},
	/*
	func: sendtoserver
	Actually sends the request to the server and sets up the appropriate callbacks.

	On error:
	Alerts the error message and all details about it.
	*/
	sendtoserver:function(handlerpath, argstring, on_request_complete, queue_callback){


		if(Server.use_disconnected_mode){
			//fake this using whatever the user cares to enter
			var fake_response = prompt("Enter the server response you want to simulate");
			on_request_complete(fake_response);				 
			queue_callback();
		}else{
			try{
				this.xh.open("POST", handlerpath, true);
				this.xh.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				this.xh.onreadystatechange = function(){
					if(Server.xh.readyState==4){
						on_request_complete(Server.xh.responseText);
						queue_callback();
					}
				};
				this.xh.send(argstring);
			}catch(e){
				DevelopNotice.fatal('core::send->' + e.message + "," + e.name + "," + e.stack + "," + e.lineNumber + "," + e.fileName);
			}
		}

		
	},
	//gets all form data and exposes it to the server for processing
	collect_all_form_data:function(){
	  var fd = {};
	  
	  $$('select').each(function(item){
		try{
		  if(item.id != null && item.id != '') fd[item.id] = $F(item);
		}catch(ex){
		  //probably no ID assigned to this element--hide error
		  alert('X'+ex);
		}
	  });
	  
	  $$('input').each(function(item){
		try{
		  if(item.id != null && item.id != '') fd[item.id] = $F(item);
		}catch(ex){
		  //probably no ID assigned to this element--hide error
		  alert('X'+ex);
		}
	  });
	  
	  $$('textarea').each(function(item){
		try{
		  if(item.id != null && item.id != '') fd[item.id] = $F(item);
		}catch(ex){
		  //probably no ID assigned to this element--hide error
		  alert('X'+ex);
		}
	  });
	  
	  //uncomment to see what is in the form data object
	  //alert(Object.keys(fd).collect(function(y){return y+':\n'+fd[y];}).join('\n'));
	  
	  return fd;
	},
  init:function(){
    /*@cc_on @*/
    /*@if (@_jscript_version >= 5)
        try{
          Server.xh = new ActiveXObject("Msxml2.XMLHTTP");
        }catch(e){
          try{
            Server.xh = new ActiveXObject("Microsoft.XMLHTTP");
          }catch(err){
              Server.xh=false;
          }
        }
        @end @*/
    if(!Server.xh && typeof XMLHttpRequest != 'undefined'){
      Server.xh=new XMLHttpRequest();
    }
  }
}












//modified from http://www.quirksmode.org/js/cookies.html
var Cookie = {
  create:function(name,value,days) {
    if(days){
      var date = new Date();
      date.setTime(date.getTime()+(days*24*60*60*1000));
      var expires = "; expires="+date.toGMTString();
    }
    else var expires = "";
    document.cookie = name+"="+value+expires+"; path=/";
  },
  read:function(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
      var c = ca[i];
      while (c.charAt(0)==' ') c = c.substring(1,c.length);
      if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
  },
  erase:function(name) {
    createCookie(name,"",-1);
  }
}


//modified from http://www.quirksmode.org/js/detect.html
var BrowserDetect = {
  ie6:false,
  ie7:false,
  ie8:false,//really this is IE >= 8
  firefox:false,
  safari:false,
  
  windows:false,
  mac:false,
  linux:false,
  
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
		
		if(this.browser=="Explorer" && this.version==6) this.ie6 = true;
    if(this.browser=="Explorer" && this.version==7) this.ie7 = true;
    if(this.browser=="Explorer" && this.version>=8) this.ie8 = true;
    
    if(this.browser=="Safari") this.safari = true;
    if(this.browser=="Firefox") this.firefox = true;
    
    if(this.OS=="Mac") this.mac = true;
    if(this.OS=="Windows") this.windows = true;
    if(this.OS=="Linux") this.linux = true;
    
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();























