
Ajax.Application = {}

Ajax.Application.Base = Class.create(); 
Ajax.Application.Cache = Class.create();

Object.extend(Ajax.Application.Base.prototype,
						{
							method : "post",
							
							sendRequest : function(dto, cb){
								var p = this.compileDTO(dto);
										
								//var t =s;
								new Ajax.Request(this.url,
													{
														parameters   : p,
														method		 : this.method,
														//onSuccess   : function (transport) { this.receiveRequest.bindAsEventListener(this, cb, transport) },
														onSuccess   : this.receiveRequest.bind(this, cb),
														onFailure    : this.ajaxFailure.bind(this),
														onException  : this.ajaxException.bind(this)
													}
												);					
							},
							
							receiveRequest : function(cb, eAja, transport){
							    //var t =s;
							    try{
								//var responseObj = ((transport.responseXML.text) ? transport.responseXML.text.evalJSON() : transport.responseXML.lastChild.textContent.evalJSON());
								cb(eAja);//,responseObj);
								} catch(err)
								{
								    alert (err.message);
								}
										
							},
							ajaxFailure : function(transport){
//								if(typeof console == "object")
//									console.log("Ajax Request failed args = %o ", arguments);
//								else
									alert("Ajax request has failed. Application integrity has been compromised.");
							},
							ajaxException : function(transport){
								
								if(typeof console == "object")
									console.log("ajax exception occured args = %o", arguments);
									alert('error');
								
							},
							compileDTO : function(dto){
								
								if(typeof dto == "object")
									return $H(dto).toQueryString();
								else if(typeof dto == "string")
									return dto;
								else
									throw { message : "object sent to sendRequest was invalid type.  Type = " +typeof dto };
										
								
							}
						
						
						}
			);

/**
 * @author Matthew Foster
 * @date   April 24th 2007
 * @purpose	This class is an extension of the base class with added functionality to allow for transparent caching.  The idea is to save the query string as a key in a hash object
 * 			and if that query string has already been sent for it will already have an ajax response and it will simply pass that immediately to the call back function
 */
Object.extend(Object.extend(Ajax.Application.Cache.prototype, Ajax.Application.Base.prototype),
					{
						getCache : function(){
							
							if(!this.requestCache)
								this.requestCache = {};
							
							return this.requestCache;
						
						},
						setCache : function(obj){
						
							Object.extend(this.requestCache, obj || {});
						
						},
						sendRequest : function(dto, cb){
							
							var cache = this.getCache();
							
							var key = this.compileDTO(dto);
							
							if(!cache[key]){
								var cachedCallBack = this.registerCache.bind(this, cb, key);
								Ajax.Application.Base.prototype.sendRequest.apply(this, [key, cachedCallBack]);
							}
							else
								cb(cache[key]);
						},
						registerCache : function(cb, key, eAja){
							var cache = {};
							
							cache[key] = eAja;
							
							this.setCache(cache);
							
							cb(eAja);
							
						}				
					}
			);// JavaScript Document
/**
 * @author 		Matthew Foster
 * @date		June 6th 2007
 * @purpose		To have a base class to extend subclasses from to inherit event dispatching functionality.
 * @procedure	Use a hash of event "types" that will contain an array of functions to execute.  The logic is if any function explicitally returns false the chain will halt execution.
 */
 var EventDispatcher = Class.create({});
	
	
	Object.extend(EventDispatcher.prototype,
					{
						
						buildListenerChain : function(){
							
							if(!this.listenerChain)
								this.listenerChain = {};							
						
						},
						addEventListener : function(type, listener){
							
							this.buildListenerChain();
							
							if(!this.listenerChain[type])					
								this.listenerChain[type] = [listener];
							else
								this.listenerChain[type].push(listener);
							
						},
						hasEventListener : function(type){
							
							return (typeof this.listenerChain[type] != "undefined");
						
						},
						removeEventListener : function(type, listener){
							if(!this.hasEventListener(type))
								return false;
								
							for(var i = 0; i < this.listenerChain[type].length; i++)
								if(this.listenerChain[type][i] == listener)
									this.listenerChain[type].splice(i, 1);
						
						},
						dispatchEvent : function(type, args){
							this.buildListenerChain();
							
							if(!this.hasEventListener(type))
								return false;
								
							this.listenerChain[type].any(function(f){ return (f(args) == false ? true : false); });						
						},
						on : function(type, listener){
							this.addEventListener(type, listener);
						},
						fire : function(type, args){
							this.dispatchEvent(type, args);
						}
					}
					
				);Ajax.Application.Event = function(){};
		
Object.extend(Object.extend(Ajax.Application.Event.prototype, Ajax.Application.Base.prototype), EventDispatcher.prototype);

Ajax.Service = {};
	
Ajax.Service.Base = function(){};

Ajax.Service.History = function(){};
	
Object.extend(Object.extend(Ajax.Service.Base.prototype, Ajax.Application.Event.prototype),
	{
		sendRequest : function(dto, cb){
			
			this.dispatchEvent("request", dto);
			
			Ajax.Application.Event.prototype.sendRequest.apply(this, [dto, cb]);
		
		},
		receiveRequest : function(cb, eAja){
			
			this.dispatchEvent("response", eAja);
			
			Ajax.Application.Event.prototype.receiveRequest.apply(this, [cb, eAja]);
		
		}
		
	}
);


//Object.extend(Object.extend(Ajax.Service.History.prototype, Ajax.Service.Base.prototype),
//	{
//		
//			buildInterface : function(obj){
//				
//				this.historyArr = [];
//				this.historyIndex = undefined;
//				
//				
//				this.container = $(obj);
//				this.historyFrame = this.container.down("iframe");
//				this.form = this.container.down("form");
//			
//			},
//			attachListener : function(){
//				
//				Event.observe(this.historyFrame, "load", this.reloadHandle);
//									
//			},
//			createListener : function(){
//												
//				this.reloadHandle = this.handleReload.bindAsEventListener(this);
//			
//			},
//			handleReload : function(e){
//							
//				var index = this.getHistoryIndex();
//				
//				var obj = this.historyArr[index];
//				
//				if(!obj)
//					return true;
//				
//				this.historyIndex = index+1;
//				
//				this.dispatchEvent("reload", [obj, index]);
//				this.dispatchEvent(obj.type, obj.arg);
//				
//			
//			},
//			
//			getHistoryIndex : function(){
//				
//				return parseInt(this.getIndex(this.historyFrame.contentWindow.location.toString()));
//				
//			},
//			getIndex : function(str){
//				
//				return str.replace(/.*historyindex=/gi, "");
//			
//			},
//			getQuery : function(str){
//				
//				return str.replace(/[^?]+?/gi, "");
//			
//			},
//			
//			registerRequest : function(type, eAja){
//			
//				if(this.historyIndex && this.historyIndex < this.historyArr.length)
//					this.historyArr.length = this.historyIndex;
//					
//				//Change iframe title
//				
//					
//				this.form.index.value = this.historyArr.length;    
//				this.historyArr.push({ type : type, arg : eAja});
//				this.form.submit();
//			}
//	
//	
//	
//	}
//);


//Ajax.Service.Bookmark = Class.create();
//		
//Object.extend(Object.extend(Ajax.Service.Bookmark.prototype, Ajax.Service.Base.prototype),
//	{
//		getBookmarkHash : function(){
//			
//			if(!this.bookmarkHash)
//				return this.bookmarkHash = $H();
//			
//			return this.bookmarkHash;
//		
//		
//		},
//		getOperation : function(name){
//		
//			return this.getBookmarkHash()[name];
//										
//		},
//		setOperation : function(name, arg){
//		
//			this.getBookmarkHash()[name] = arg;
//		
//		},
//		getOperationKeys : function(){
//			
//			return this.getBookmarkHash().keys();
//		
//		}
//	
//	}
//);

//Ajax.Service.BookmarkHistory = Class.create();


//Object.extend(Object.extend(Ajax.Service.BookmarkHistory.prototype, Ajax.Service.History.prototype),
//	{
//		
//		buildInterface : function(){
//		
//			Ajax.Service.History.prototype.buildInterface.apply(this, arguments);
//			this.historyRequestList = [];				
//		
//		},					
//		sendRequest : function(dto, cb){
//		
//			Ajax.Application.Base.prototype.sendRequest.apply(this, arguments);
//			
//			this.registerRequest(dto, cb);
//						
//		},
//		registerRequest : function(dto){
//		
//			this.historyRequestList.push(dto);					
//		
//		},
//		registerResponse : function(){
//		
//			Ajax.Service.History.prototype.registerRequest.apply(this, arguments);
//							
//		},
//		handleReload : function(e){
//		
//			var index = this.getHistoryIndex();
//			
//			var obj = this.getResponseHistory(index);
//			
//			if(!obj)
//				return true;
//			
//			var reqObj = this.getRequestHistory(index);
//			
//			this.historyIndex = index+1;
//			
//			this.dispatchEvent("request", reqObj);
//			this.dispatchEvent("response", obj);
//			this.dispatchEvent(obj.type, obj.arg);					
//		
//		},
//		getResponseHistory : function(num){
//			
//			return this.historyArr[num];
//		
//		},
//		getRequestHistory : function(num){
//		
//			return this.historyRequestList[num];
//		
//		},
//		getBookmarkHash : function(){
//			
//			if(!this.bookmarkHash)
//				return this.bookmarkHash = $H();
//			
//			return this.bookmarkHash;
//		
//		
//		},
//		getOperation : function(name){
//		
//			return this.getBookmarkHash()[name];
//										
//		},
//		setOperation : function(name, arg){
//		
//			this.getBookmarkHash()[name] = arg;
//		
//		},
//		getOperationKeys : function(){
//			
//			return this.getBookmarkHash().keys();
//		
//		}
//	
//	}
//);
//var EventFormBase = Class.create();

//Object.extend(Object.extend(EventFormBase.prototype, EventDispatcher.prototype),
//		{
//			createListener : function(){
//			
//				this.submitHandle = this.handleSubmit.bindAsEventListener(this);
//			
//			},
//			attachListener : function(){
//				
//				Event.observe(this.form, "submit", this.submitHandle);
//			
//			},
//			buildInterface : function(form){
//				
//				this.form = $(form);
//			
//			},
//			handleSubmit : function(e){
//				
//				Event.stop(e);
//				
//				this.dispatchEvent("submit", this.form.serialize(true));		
//			
//			}	
//		
//		}
//	);
//				
//var EventFormBase = Class.create();

//Object.extend(Object.extend(EventFormBase.prototype, EventDispatcher.prototype),
//	{
//		createListener : function(){
//		
//			this.submitHandle = this.handleSubmit.bindAsEventListener(this);
//		
//		},
//		attachListener : function(){
//			
//			Event.observe(this.form, "submit", this.submitHandle);
//		
//		},
//		buildInterface : function(form){
//			
//			this.form = $(form);
//		
//		},
//		handleSubmit : function(e){
//			
//			Event.stop(e);
//			
//			this.dispatchEvent("submit", this.form.serialize(true));		
//		
//		}	
//	
//	}
//);					