YAHOO.namespace("Unyk.Web.UI");
var Unyk = YAHOO.Unyk;


//*****************************************************************************
//
//	Unyk.Web
//
//*****************************************************************************

//
//	Base class for web services calls.
//
Unyk.Web.WebServiceProxy = function()
{
};

Unyk.Web.WebServiceProxy.prototype = 
{	

	//*************************************************************************
	//
	//	Private API
	//
	//*************************************************************************
	
	//
	//	...
	//
	_CreateCallback : function(onSuccess, onFailure)
	{
		return {
			customevents : {
				//onComplete : onComplete,
				onFailure : (onFailure) ? onFailure : function(){},
				onSuccess : (onSuccess) ? onSuccess : function(){}
			}
		}
	},


	//
	//	...
	//
	_CreateBody : function(useGet, params)
	{
		var body = null;
		
		if (!useGet)
		{
			body = this._CreateQueryString(params);
		}
		
		return body;
	},
	
	
	//
	//	...
	//
	_CreateQueryString : function(params)
	{
		var querystring = [];
		
		for (arg in params)
		{
			var value = JSON.stringify(params[arg]);
			
			/*
			// Remove enclosing '"' ("value" --> value).
			if (value.substring(0, 1) === "\"" && 
				value.substring(value.length - 1) === "\"")
			{
				value = value.substring(1, value.length - 1);
			}
			*/
			
			querystring[querystring.length] = 
				encodeURIComponent(arg) +"="+ encodeURIComponent(value);
		}
		
		return querystring.join("&");
	},
	
	
	//
	//	...
	//
	_CreateUrl : function(servicePath, commandName, params, useGet)
	{
		var url = servicePath +"/"+ commandName;
		
		if (useGet && params)
		{
			var qs = this._CreateQueryString(params);
			if (qs.length > 0)
			{
				url = url +"?"+ qs;
			}
		}
		
		return url;
	},
	
	
	//
	//	...
	//
	_ExecuteCommand : function(servicePath, commandName, useGet, params, callback)
	{
		var httpVerb = useGet ? "GET" : "POST";
		var url = this._CreateUrl(servicePath, commandName, params, useGet);
		//var callback = this._CreateCallback(onSuccess, onFailure);
		var body = this._CreateBody(useGet, params);

		this._InitHeaders();
		
		return Connect.asyncRequest(httpVerb, url, callback, body);
	},
	
	
	//
	//	Initialize the request headers.
	//
	_InitHeaders : function()
	{
		// Headers has to be reset for each request since
		// YAHOO.util.Connection is a singleton.
		Connect.resetDefaultHeaders();
	}
	
};


//
//	Base class for the implementation of a page's page methods.
//
Unyk.Web.PageMethodsProxy = function()
{
	Unyk.Web.WebServiceProxy.call(this);
};

YAHOO.lang.extend(Unyk.Web.PageMethodsProxy, Unyk.Web.WebServiceProxy, 
{

	//*************************************************************************
	//
	//	Fields
	//
	//*************************************************************************
	
	//
	//	Get or Set the WebService path.
	//
	Path : "",
	


	//*************************************************************************
	//
	//	Private API
	//
	//*************************************************************************
	
	//
	//	Overrides WebServiceProxy._CreateBody.
	//
	_CreateBody : function(useGet, params)
	{
		var body = null;
		
		if (!useGet)
		{
			body = JSON.stringify(params);
			if (body === "{}") body = "";
		}
		
		return body;
	},
	
	
	//
	//	...
	//
	_CreateUrl : function(servicePath, commandName, params, useGet)
	{
		var url = servicePath;
		
		// Append the command name as a query string.
		url += "?"+ this._CreateQueryString({pm : commandName});
		
		// If it's a GET request, append the other params.
		if (useGet)
		{
			var qs = this._CreateQueryString(params);
			if (qs.length > 0)
			{
				url += "&"+ qs;
			}
		}
		
		if (Unyk.Web.UI.Querystrings.Items["nub"])
		{
			// There's a nub, happen it to the url.
			// (This solve the bug where IE doesn't recognize cookies for urls like
			//	http://fred/page.asp. It considers the domain to be invalid).
			url += "&nub="+ Unyk.Web.UI.Querystrings.Items["nub"];
		}
		
		return url;
	},
	
	
	//
	//	Overrides WebServiceProxy._InitHeaders.
	//	Need to specify the Content-Type header so its json-parsed
	//	server-side.
	//
	_InitHeaders : function()
	{
		Unyk.Web.WebServiceProxy.prototype._InitHeaders.call(this);
		
		Connect.setDefaultPostHeader(false);
		Connect.initHeader("Content-Type", "application/json; charset=utf-8");
	}
	
});



//*****************************************************************************
//
//	Unyk.Web.UI
//
//*****************************************************************************

//
//	Base class for the js pages.
//
Unyk.Web.UI.Page = function(isAsync)
{
	if (!isAsync)
	{
		Event.onDOMReady(this.Page_Load, null, this); // Make sure that "this" inside Page_Load refers to the object.
		Event.onDOMReady(Unyk.Common.AddTargetBlankHandler);

		Event.DOMReadyEvent.unsubscribe(Unyk.Common.AddViadeoBarHandler);
		Event.onDOMReady(Unyk.Common.AddViadeoBarHandler);
	}
	else
	{
		// Page is ready already!
		this.Page_Load();
		Unyk.Common.AddTargetBlankHandler();
		Unyk.Common.AddViadeoBarHandler();
	}
};

Unyk.Web.UI.Page.prototype = 
{

	//*************************************************************************
	//
	//	Fields
	//
	//*************************************************************************
	_formsState : {},
	
	
	
	//*************************************************************************
	//
	//	Properties
	//
	//*************************************************************************
	
	//
	//	Get or Set the form that data is submitted to using the __doPostBack
	//	method.
	//
	Form : null,
	
	
	
	//*************************************************************************
	//
	//	Events
	//
	//*************************************************************************
	
	//
	//	Handles the Page Load event.
	//
	Page_Load : function(e, args)
	{
	},
	
	
	//
	//	Handles the Page BeforeUnload event.
	//
	Page_BeforeUnload : function(e, args)
	{
		for (var form in this._formsState)
		{
			if (this._formsState[form].isChanged)
			{
				e.returnValue = this._formsState[form].warning;
				return;
			}
		}
	},


	//
	//	Handles the change of any control in the form that affect its state.
	//
	ControlCapslockSate_KeyPress : function(e, args)
	{
		var sender = Event.getTarget(e);

		if (args.controls && args.controls.length > 0)
		{
			// Find the control triggering the event.
			for (var i = 0; i < args.controls.length; i++)
			{
				if ($(args.controls[i]).id == sender.id)
				{
					args.callback(this.IsCapslockOn(e));
				}
			}
		}
	},


	//
	//	Handles the change of any control in the form that affect its state.
	//
	ControlFormSate_Change : function(e, args)
	{
		var sender = Event.getTarget(e);
		var stateChanged = true;

		if (args.form)
		{
			if (args.controls && args.controls.length > 0)
			{
				stateChanged = false;

				for (var i = 0; i < args.controls.length; i++)
				{
					if ($(args.controls[i]).id == sender.id)
						stateChanged = true;
				}
			}

			this._formsState[args.form.id] = {isChanged: stateChanged, warning: args.warning};
		}
	},



	//*************************************************************************
	//
	//	Private API
	//
	//*************************************************************************

	//
	//	...
	//	
	//	eventTarget:	...
	//	eventArgument:	...
	//	form:			...
	//	
	__doPostBack : function(eventTarget, eventArgument, form)
	{
		form = $(form || this.Form);

		if ($("__EVENTTARGET")) $("__EVENTTARGET").value = eventTarget;
		if ($("__EVENTARGUMENT")) $("__EVENTARGUMENT").value = eventArgument;
		if (form)
		{
			if (this._formsState[form.id])
				this._formsState[form.id].isChanged = false;

			form.submit();
		}
	},


	//
	//	Enables the state tracking for the capslock.
	//
	TrackCapslockState : function(controls, callback)
	{
		// Make controls is an array
		if (!YAHOO.lang.isArray(controls))
			controls = [controls];

		Event.on(controls, "keypress", this.ControlCapslockSate_KeyPress, {controls: controls, callback: callback}, this);
	},


	//
	//	Enables the state tracking for the specified form.
	//
	TrackFormState : function(warning, form, controls)
	{
		form = $(form || this.Form);
		var target = form;

		// IEvil doesn't bubble the change event, so I'm registering it for
		// each control instead.
		if (YAHOO.env.ua.ie > 0)
		{
			// Register only the tracked controls if any, else track all form fields.
			if (controls && controls.length)
				target = controls;
			else
				target = Dom.getElementsBy(
					function(e)	{ 
						return e.nodeName.toLowerCase() == "input" ||
							e.nodeName.toLowerCase() == "select" ||
							e.nodeName.toLowerCase() == "textarea";
					},
					"",
					form
				);
		}

		Event.on(target, "change", this.ControlFormSate_Change, {form: form, warning: warning, controls: controls}, this);
		Event.on(window, "beforeunload", this.Page_BeforeUnload, null, this);
	},


	//
	//	Determines if Capslock is on or off.
	//
	IsCapslockOn : function(e)
	{
		var charCode = Event.getCharCode(e);

		//if upper case, check if shift is not pressed. if lower case, check if shift is pressed
		return (
			(charCode > 64 && charCode < 91 && !e.shiftKey) || 
			(charCode > 96 && charCode < 123 && e.shiftKey)
		);
	}

};


//
//	Represents the Querystrings of the current browsing Url.
//
Unyk.Web.UI.Querystrings = function()
{
	this.ParseQuerystring(window.location.search);
};

Unyk.Web.UI.Querystrings.prototype = 
{

	//*************************************************************************
	//
	//	Fields
	//
	//*************************************************************************
	Items : {},
	
	
	
	//*************************************************************************
	//
	//	Private API
	//
	//*************************************************************************

	//
	//
	//
	ParseQuerystring : function(q)
	{
		if (q.length > 1)
			q = q.substring(1, q.length);
		else 
			q = null;
			
		if (q)
		{
			var keyValuePairs = q.split("&");
			
			for (var i = 0; i < keyValuePairs.length; i++)
			{
				var key = keyValuePairs[i].split("=")[0];
				var value = keyValuePairs[i].split("=")[1];
				
				this.Items[key] = value;
			}
		}
	}
	
};

//	Makes the Querystrings a singleton.
Unyk.Web.UI.Querystrings = new Unyk.Web.UI.Querystrings();
