/*!*******************************************************************************
|	$Revision: 4 $
|	$Date: 2009-10-22 10:02:08 +0200 (Thu, 22 Oct 2009) $
|
********************************************************************************/  

/* Request
----------------------------------------------------------------------------*/

CP.set( 'Request', {
	initialize: function()
	{
		this._request = null;
		this.dataType = 'json';
		this.method = 'GET';
		this.url = '';
		this.postData = null;
		this.cache = false;

		this.handlers = {
			before: null,
			complete: null, // called when an ajax request returns
			success: null,	// called when the response arrived width a status = 1
			error: null, // called when the response arrived width a status = 0
			serverError: null // called after a network/server error
		};
	}
	,getMethod: function()
	{
		return this.method;
	}
	,setMethod: function( method )
	{
		var methods = [ 'POST', 'GET' ];
		method = method.toUpperCase() || 'GET';
		
		if( $.inArray( method, methods ) != -1 )
			this.method = method;
		
		return this;
	}
	,getUrl: function()
	{
		return this.url;
	}	
	,setUrl: function( url, appendBase )
	{
		this.url = ( appendBase == true ) ? CP.BASE_HREF + url : url;
		
		return this;
	}
	,getData: function()
	{
		return this.postData;
	}
	,setData: function( data )
	{		
		if( isObject( data ) )
		{
			this.postData = $.serializeObject( data );			
		}
		else
		{
			if( data == '' )
				data = null;			
			this.postData = data;			
		}

		return this;
	}
	,setHandlers: function( handlers )
	{
		this.handlers = $.extend( this.handlers, handlers );
		return this;		
	}	
	,send: function( options )
	{
		var _this = this,
			_options = {
				type: this.method,
				url: this.url,
				dataType: this.dataType,
				data: this.postData,
				cache: this.cache,
				beforeSend: function( xhr )
				{
					_this._beforeHandler.apply( _this, arguments );
				},
				complete: function( xhr, textStatus )
				{
					_this._completeHandler.apply( _this, arguments );
				},
				success: function( data, textStatus )
				{
					_this._successHandler.apply( _this, arguments );
				},
				error: function( xhr, textStatus, errorThrown )
				{
					_this._serverErrorHandler.apply( _this, arguments );
				}
			};

		this._request = $.ajax( $.extend( {}, _options, options ) );
	}
	,abort: function()
	{
		if( this._request )
			this._request.abort();
		return this;
	}
	,_beforeHandler: function( xhr )
	{
		var _this = this;

		if( $.isFunction( this.handlers.before ) )
			this.handlers.before( xhr );		
	}	
	,_completeHandler: function( xhr, textStatus )
	{
		var _this = this;

		if( $.isFunction( this.handlers.complete ) )
			this.handlers.complete( xhr );		
	}
	,_successHandler: function( data, textStatus )
	{
		var resp = new CP.Response( data );

		// if the response was a success, fire a success cb
		// if the response was a failure, fire an error cb
		if( resp.getStatus() )
		{
			if( $.isFunction( this.handlers.success ) )
				this.handlers.success( resp );			
		}
		else
		{
			// this._handleStatusCodes( resp.getErrorCode(), resp, null );
			
			if( $.isFunction( this.handlers.error ) )
				this.handlers.error( resp );			
		}
	}
	,_serverErrorHandler: function( xhr, textStatus, errorThrown )
	{
		if( $.isFunction( this.handlers.serverError ) )
			this.handlers.serverError( xhr );
			
		this._showErrorConsole( xhr.responseText );

		this._handleStatusCodes( xhr.status );
	}
	,_handleStatusCodes: function( statusCode, response, xhr )
	{
		statusCode = parseInt( statusCode );

		switch( statusCode )
		{
			case 403:
				alert( this.url + '\n' + __( 'You are not allowed to access the requested URL.' ) );
				break;
			case 404:
				alert( this.url + '\n' + __( 'The requested page was not found.' ) );
				break;
		}
	}
	,_showErrorConsole: function( error )
	{
		if( CP.DEBUG )
		{
			var consoleId = '#cp-request-error-console',
				_console = $( consoleId );
			
			if( _console.size() )
				_console.remove();
				
			_console = $( '<div></div>' )
				.attr({
					'id': consoleId,
					'class': 'cp-request-console'
				})
				.css({
					height: 200,
					width: '100%',
					background: '#FFF',
					opacity: 0.9,
					padding: '10px',
					position: 'fixed',
					overflow: 'auto',
					bottom: '0px'
				});
				
			_console.append( $( '<p>' + new Date() + ' - <b>' + this.method + ' ' + this.url +'</b></p>' ).css({
				padding: '0 0 10px 0',
				margin: 0
			}));
			_console.append( $( '<textarea>' + error + '</textarea>' ).css({
				padding: 0,
				border: 0,
				width: '100%',
				height: 180
			}));

			$( "body" ).append( _console );
		}
	}
});

/* Response
----------------------------------------------------------------------------*/

CP.set( 'Response', {
	initialize: function( data )
	{
		var _defaults = {
			status: 0,
			errorType: '',
			errorMessage: '',
			message: '',
			payload: {},
			onLoad: ''		
		}

		this._response = $.extend( {}, _defaults, data );
	}
	,getStatus: function()
	{
		return this._response.status == 1;
	}
	,getMessage: function()
	{
		return this._response.message;
	}
	,getError: function()
	{
		return this._response.errorMessage;
	}
	,isError: function()
	{
		return this._response.status == 0 && this._response.errorType != 'warning';
	}	
	,isWarning: function()
	{
		return this._response.status != 1 && this._response.errorType == 'warning';
	}
	,getPayload: function()
	{
		return this._response.payload;
	}
	,getField: function( field )
	{
		return this._response.payload[ field ] || null;
	}
});