﻿
var AjaxRequest = Class.create({

	initialize : function(method, args, options)
	{
		this.MethodName = method;
		this.Args = args || [];
		this.options = Object.extend({
			CallbackPage: null,
			Asynchronous: true,
			Method: "post",
			OnError: null,
			ResponseType: AjaxManager.ResponseType.Standard
		}, options || { });
		
		this.requestUrl = null;
		this.requestBody = null;
		
	},
	
	RequestURL: function()
	{
		if(!this.requestUrl)
		{
			var url;
			if(!this.options.CallbackPage)
				url = AjaxManager.CallbackPages[this.MethodName];
			else
				url = this.options.CallbackPage;
				
			if(this.options.Method == 'get' && this.MethodName)
			{
				var requestParams = { Method: this.MethodName, Args: this.Args };
				var serializedRequest = Object.toJSON(requestParams);
				url += "?AJAX=true&RESPONSE=";
				url += this.options.ResponseType;
				url += "&AJAXREQUEST=";
				url += serializedRequest;
			}
			
			this.requestURL = url;
		}
		
		return this.requestURL;
		
	},
	
	RequestBody: function()
	{
		if(!this.requestBody)
		{
			var requestParams = { Method: this.MethodName, Args: this.Args };
			var serializedRequest = Object.toJSON(requestParams);
			var body = "";
			if(this.options.Method == 'post')
				body = "AJAX=true&RESPONSE=" + this.options.ResponseType + "&AJAXREQUEST=" +  serializedRequest;
				
			this.requestBody = body;
		}
		
		return this.requestBody;
	}
});

function AjaxResponse(message, output, error)
{
	this.HasError = (error != null);
	this.Error = error;
	this.Message = message;
	this.Output = output;
	
}

function AjaxError(type, message, stacktrace)
{
	this.Type = type;
	this.Message = message;
	this.StackTrace = stacktrace;
	this.InnerError = null;
}

var AjaxManager =
{
	ResponseType:
		{
			Standard: "STANDARD",
			Xml: "XML",
			Literal: "LITERAL"
		},
		
	PendingRequests: new Hash(),
	
	Cleanup: function()
	{
		AjaxManager.PendingRequests.each(function(kvp)
		{
			var req = kvp.value;
			if(req.transport.readyState != 4)
			{
				try
				{
					req.transport.abort();
				}
				catch(ex)
				{
					//alert("error while aborting request: " + ex.message);
				}
			}
		})
	},
		
	Call: function(methodName, args, callback, options)
		{
			var result = null;
			
			if(options)
				options.onSuccess = callback;
			else
				options = { onSuccess: callback };
				
			var ajaxRequest = new AjaxRequest(methodName, args, options);
			
			var postBody = ajaxRequest.RequestBody();		
			var opts = 
			{
				asynchronous: ajaxRequest.options.Asynchronous,
				method: ajaxRequest.options.Method,
				onSuccess: AjaxManager.OnAjaxSuccess.curry(ajaxRequest),
				onException: options.onException || AjaxManager.OnAjaxException,
				onFailure: options.onFailure || Prototype.K
			}
			if(postBody)
				opts.postBody = postBody;
			
			var request = new Ajax.Request(ajaxRequest.RequestURL(), opts);
			
			if(ajaxRequest.options.Asynchronous == false)
			{
				var response = new Ajax.Response(request)
				var responseType = ajaxRequest.options.ResponseType;
				if(responseType == AjaxManager.ResponseType.Standard)
					result = response.responseJSON;					
				else if(responseType == AjaxManager.ResponseType.Xml)
					result = resposne.responseXML;
				else
					result = response.responseText;
			}
			else
			{
				//do not include "LogActivities" in the list of requests to cancel on page unload
				if(methodName != "LogActivities")
				{
					request.id = (new Date()).getTime();
					AjaxManager.PendingRequests.set(request.id, request);
				}
				result = request;
			}
			
			
			
			return result;
		},
		
		OnAjaxSuccess: function(ajaxRequest, response)
			{
				var responseType = ajaxRequest.options.ResponseType;
				var arg;
				if(responseType == AjaxManager.ResponseType.Standard)
					arg = response.responseJSON;
				else if (responseType == AjaxManager.ResponseType.Xml)
					arg = response.responseXML;
				else
					arg = response.responseText;
				
				AjaxManager.PendingRequests.unset(response.request.id);
					
				if(ajaxRequest.options.onSuccess)
					ajaxRequest.options.onSuccess(arg);
			},
			
		OnAjaxFailure: function(ajaxRequest, response)
			{
				var responseType = ajaxRequest.options.ResponseType;
				var arg;
				if(responseType == AjaxManager.ResponseType.Standard)
					arg = new AjaxResponse(response.statusText, "", response.statusText);
				else
					arg = "";
				
				AjaxManager.PendingRequests.unset(response.request.id);
				
				if(ajaxRequest.options.onSuccess)
					ajaxRequest.options.onSuccess(arg);
			},
			
		OnAjaxException: function(request, ex)
			{
				if(request.options.onException != AjaxManager.OnAjaxException)
					request.options.onException(request, ex);
				else if(showAjaxErrors)
					alert("Ajax Error: " + ex.message);
				
				if(typeof(response) != 'undefined')
					AjaxManager.PendingRequests.unset(response.request.id);
			}
}

Acceller.AddUnloadListener(AjaxManager.Cleanup);

AjaxManager.CallbackPages =
{
	GetOfferAvailability: "Dispatch.ashx",
	QualifyAddress: "ShowOffers.ashx",
	RenderOfferDetails: "ShowOffers.ashx",
	RenderOfferControl: "ShowOffers.ashx",
	SwitchViewMode: "ShowOffers.ashx",
	RemoveOffer: "ShowOffers.ashx",
	ChooseOffer: "ShowOffers.ashx",
	ChooseMultipleOffers: "ShowOffers.ashx",
	RenderArticleHTML: "ShowOffers.ashx",
	ValidateSelection: "ShowOffers.ashx",
	FilterClicked: "ShowOffers.ashx",
	RenderPriceDisclaimer: "ShowOffers.ashx",
	LogActivities: "ShowOffers.ashx",
	ValidateOrder: "PlaceOrder.ashx",
	CompareCustomization: "PlaceOrder.ashx",
	ShowTermsAndConditions: "PlaceOrder.ashx",
	SubmitOrder: "PlaceOrder.ashx",
	RenderBillingInfo: "PlaceOrder.ashx",
	RenderOrderAttachmentOffers: "OrderConfirmation.ashx",
	RenderAttachmentDetails: "OrderConfirmation.ashx",
	RenderAttachmentTerms: "OrderConfirmation.ashx",
	OrderAttachmentsSelect: "OrderConfirmation.ashx",
	OrderAttachmentSubmit: "OrderConfirmation.ashx",
	RegisterConfirmationUpsell: "OrderConfirmation.ashx",
	SendConfirmationEmailCC: "OrderConfirmation.ashx",
	CCPreOverride: "PlaceOrder.ashx",
	SubmitWarmTransfer: "OrderConfirmation.ashx",
	RenderProviderResults: "ShowOffers.ashx",
	SwitchPreferredOfferMode: "ShowOffers.ashx",
	RenderPriceDetails: "ShowOffers.ashx",
	SendSessionEmail: "ShowOffers.ashx",
	RemoveValidationGroups: "PlaceOrder.ashx"
}