/**
 * @class ep
 *
 */

/*
 * @copyright		© Copyright 2006-2010, epages GmbH, All Rights Reserved.
 *
 * @module			ep.ajax
 *
 * @revision		$Revision: 1.8 $
 */

define("ep/ajax", [
	"jquery",
	"ep",

    "jquery/cookie",
], function ($, ep) {

	$.ajaxSetup({
		fileSizeMax: (ep.config.maxContentLength || 5120) * 1024
	});

	ep.extend({
		/**
		 * Perform an asynchronous HTTP (Ajax) request.
		 *
		 * The `ep.ajax()` function is a modified alias of `jQuery.ajax()`.
		 *
		 * If dataType json, `ep.ajax()` add "Accept", "text/x-json" to the requestHeader and set the url to `ep.config.baseUrl`.
		 * If dataType json and the response contains the ''Error'' object, `ep.ajax()` interprets the request as error.
		 *
		 * This plugin setup the default ajax-type of `jQuery.ajax()` and `ep.ajax()` to '''get'''. To change this
		 * add a "type: post" to the parameters.
		 *
		 * To do a sync requests instead of async just add "async: false" to the parameters.
		 *
		 * To prevent browser caching of the request use the parameter: "cache: false". The default behaviour is "cache: true".
		 *
		 * ====New API standard in 6.14.0====
		 * For AJAX use `deferred object` methods instead of setting `success`, `error` and `complete` methods as arguments.
		 *
		 * Properties to methods:
		 *
		 * + `success` => `.done()`
		 * + `error` => `.fail()`
		 * + `complete` => `.always()`
		 *
		 * ### Examples
		 * Perform an ajax request.
		 *
		 * JavaScript:
		 *
		 *     ep.ajax({
		 *         data: {
		 *             ObjectID: 5,
		 *             ViewAction : 'JSONGet'
		 *         },
		 *         cache: false,
		 *         type: "post",
		 *         async: false,
		 *         dataType: "json",
		 *         success:
		 *     })
		 *     .done(function( jsonData ){
		 *
		 *     });
		 *
		 *
		 * ### Dependencies
		 *
		 *  + `ep`
		 *
		 * @param {Object} options A set of key/value pairs that configure the Ajax request. All settings are optional.
		 *
		 * @method ajax
		 * @static
		 * @member ep
		 *
		 * @since 6.11.0
		 */
		ajax: function (settings) {

			var jqXHR,
				tokenName = "SecToken",
				cookies = $.cookie();

			if (!settings.url) {
				settings.url = ep.config.baseUrl;
			}

			// check if security token exists and add hidden input with security cookie information
			if (cookies[tokenName]) {
				settings.data = settings.data || {};
				settings.data[tokenName] = cookies[tokenName];
			}

			if (settings.dataType === 'json') {
				var _beforeSend = settings.beforeSend;

				// add special header for epages
				$.extend(settings, {
					beforeSend: function (xhr, s) {
						xhr.setRequestHeader("Accept", "application/json");
						if (_beforeSend) {
							_beforeSend(xhr, s);
						}
					}
				});

				// save deprecated properties as locals
				var success = settings.success,
					error = settings.error,
					complete = settings.complete;

				// delete deprecated properties
				settings.success = settings.error = settings.complete = undefined;

				// create AJAX object
				jqXHR = $.ajax(settings);

				// init
				var context = settings.context || jqXHR,
					deferred = $.Deferred(),
					complete = $.Deferred(),
					// save original deferrd methods
					originalDone = jqXHR.done,
					originalFail = jqXHR.fail;

				// set bridge for .done() calls
				originalDone(function (data, status, jqXHR) {
					if (data && data.Errors) {
						var errorThrown = data.Errors;
						jqXHR.status = 400;
						jqXHR.statusText = status = "error";
						deferred.rejectWith(context, [jqXHR, status, errorThrown]);
					} else {
						deferred.resolveWith(context, [data, status, jqXHR]);
					}
				});

				// set bridge for .fail() calls
				originalFail(function (jqXHR, status, errorThrown) {
					deferred.rejectWith(context, [jqXHR, status, errorThrown]);
				});

				// set bridge for .always() calls
				deferred.always(function () {
					complete.resolveWith(context, [jqXHR]);
				});

				// map .done() to own deferrd
				jqXHR.done = function () {
					deferred.done.apply(deferred, arguments);
					return jqXHR;
				};

				// map .fail() to own deferrd
				jqXHR.fail = function () {
					deferred.fail.apply(deferred, arguments);
					return jqXHR;
				};

				// map .always() to own deferrd
				jqXHR.always = function () {
					complete.done.apply(complete, arguments);
					return jqXHR;
				};

				// restore deprecated properties from locals
				if (success) {
					jqXHR.done(success);
				}
				if (error) {
					jqXHR.fail(error);
				}
				if (complete) {
					jqXHR.always(complete);
				}
			} else {
				jqXHR = $.ajax(settings);
			}

			return jqXHR;
		}
	});

	return ep;

});