/**
 * Description
 *
 * Copyright 2011, Nodes.dk. All Rights Reserved.
 *
 * @author kasper jensen <kj@nodes.dk>
 * @created 07-1-2011 03:04 PM
 */
(function($){
	var methods = {
		/*
		* init,
		* set the FBAuthPath url,
		* and does so dom items tagged with the FacebookRequireLoginLink class becomes login buttons
		* if used on a link, it will redirect to link path when done, or stop the link from redirection if login fails
		*/
		init:function(options){
			options = (options == undefined) ? {}:options;

			if(options.FBAuthPath != undefined) {
				configuration.FBAuthPath = options.FBAuthPath;
			}

			jQuery('.FacebookRequireLoginLink').live('click', function(e){
				var _self = jQuery(this);

				jQuery.Nodes('silentLogin', {
					callback:function(){
						jQuery.Nodes('redirect', _self.attr('href'));
					},
					scope:options['scope']
				});

				e.preventDefault();
				e.stopPropagation();
			});
		},
		/*
		* Creates a url like the cake way, doesnt currently worl that well with non standard URL's
		* needs some more work to work properly however
		* options:
		*	plugin:string		,plugin name
		*	controller:string	,controller name
		*	action:string		,action name
		*/
		url:function(options){
			if(typeof options === 'string') {
				return options;
			}

			//set variables depending on URL
			var plugin = (options.plugin != undefined) ? options.plugin:window.location.toString().split(Nodes.Router.applicationPrefix())[1].split("/")[1];
			var controller = (options.controller != undefined) ? options.controller:window.location.toString().split(Nodes.Router.applicationPrefix())[1].split("/")[2];
			var action = (options.action != undefined) ? options.action:'';

			delete options.plugin;
			delete options.controller;
			delete options.action;

			var args = "";
			for (var action_argument in options) {
				args += "/" + options[action_argument];
			}

			return Nodes.Router.applicationPrefix() + "/" + plugin + "/" + controller + "/" + action + args;
		},
		/*
		* Logs the user in silently,
		* so login dialog is only shown if needed, and sends newest session to server
		* !IMPORTANT! rememeber to set the FBAuthPath via jQuery.Nodes({FBAuthPath:"somepath"});
		* or else script wont know where to send session to
		*/
		silentLogin: function (options) {
			var options				    = jQuery.isEmptyObject(options) ? {} : options;
			options['css'] 			    = options['css'] || {};
            options['showDialog']       = (typeof options['showDialog'] == 'undefined' ? true : options['showDialog']);
			options['FBAuthPath'] 	    = options['FBAuthPath'] || configuration['FBAuthPath'];
			options['scope'] 		    = options['scope'] || '';
			options['scope']		    = jQuery.trim(options['scope']);

			// oAUTH 2.0 specs
			if(options['scope'].length > 0) {
                FB.getLoginStatus(function(response) {
					options.response = response;
                    if (response.authResponse) {
					    jQuery.Nodes('authenticateToPHP', jQuery.extend({}, options));
				    } else {
					    jQuery.Nodes('authenticateToFacebook', jQuery.extend({}, options));
				    } 
			    });
			} else {
	            jQuery.Nodes('authenticateToFacebook', jQuery.extend({}, options));
			}
		},
		authenticateToPHP: function(options) {
			jQuery.post(options.FBAuthPath, {'data': { 'facebook_session': FB.getAuthResponse() } }, function(FBAuthResponse) {
				// TODO, do something with the result, check for errors!
				if (typeof options.callback == 'function') {
					options.callback.call(this, options.response, FBAuthResponse);
				}
			});
		},
		authenticateToFacebook: function(options) {
			var defaults = {
				'error_title': Nodes.translate('fbPermissionDialog.cancel.title'),
				'error_message': Nodes.translate('fbPermissionDialog.cancel.message'),
				'css': ''
			};
			var options = jQuery.extend({}, defaults, options);

			FB.login(function(response) {
				if (response.authResponse){
					jQuery.Nodes('authenticateToPHP', jQuery.extend({}, options, { 'response': response }));
				} else {
					if(options.errorCallback) {
						options.errorCallback.call(this, response);
					}
					if(options.showDialog) {
						jQuery.Nodes('fbDialog', {
							title: options.error_title,
							message: options.error_message,
							css: options.css
						});
					}
				}
			}, {
				'scope': options['scope']
			});
		},
		userGrantedAppPermissions: function(options) {
			if(options['scope'] == ""){//return if no permission are required
				options['yes'].call();
				return;
			}
			
			var options = options;
			var required_permissions = options['scope'].split(',');

			FB.api('/me/permissions', function(response) {
				var app_permissions = response['data'][0];
				var success = true;
				jQuery(required_permissions).each(function(k, v) {
					if (typeof app_permissions[v] == "undefined") {
						success = false;
						return false;
					}
				});

				if (success) {
					options['yes'].call();
				} else {
					options['no'].call();
				}
			});
		},
		/*
		* redirect function used for javascript redirects
		* very buggy avoid using it until fixed..
		*/
		redirect:function(options){
			//#TODO add in so ajax pages are supported
			//#TODO add in so you can add post params
			//#TODO add require login option, also effectively working as a way of sending a refreshed session to the server
			window.location = jQuery.Nodes('url', options);
		},

		/*
		* fbDialog
		* show a standard dialog
		* options:
		*	css:object					,define css be appended to dialog
		*	title:string				,define dialog title
		*	message:string				,define dialog content
		*	callback:function(options)	,function called after dialog appears, recieves options as parameter
		*	onClose:function(options)	,function called after dialog is closed (on "OK"), recieves options as parameter
		*	persistant:bool=false		,removes the "close" button
		*/
		fbDialog:function(options) {
			var _self =	 this;
			//#TODO add type:"confirm" option, to turn it into a confirm dialog with a callback
			//#TODO auto scroll to the message

			//dialog html template
			var template = jQuery('<div class="popup_tpl" style="display: block; width: 350px; top: 40px; left: 40px;"> ' +
				'	<div class="p_top"> ' +
				'		<div class="p_bg1"></div> ' +
				'		<div class="p_bg2"></div> ' +
				'	</div> ' +
				'	<div class="cn_popup"> ' +
				'		<div class="p_cn_wrapper"> ' +
				'			<div class="p_title">Der opstod en fejl</div> ' +
				'			<div class="p_info_bar"></div> ' +
				'			<div class="p_pad" style="color: rgb(51, 51, 51); overflow-x: auto; overflow-y: auto; ">CONTENT HERE</div> ' +
				'		</div> ' +
				'		<div class="p_nav"> ' +
				'			<div class="p_nav_inner"> ' +
				'				<a href="#" class="p_btn p_cancel">OK</a> ' +
				'			</div> ' +
				'		</div> ' +
				'	</div> ' +
				'	<div class="p_bottom"> ' +
				'		<div class="p_bg1"></div> ' +
				'		<div class="p_bg2"></div> ' +
				'	</div> ' +
				'</div>');

			//set body position if not set already
			jQuery('body').css('position', ((jQuery('body').css('position') != "relative" && jQuery('body').css('position') != "absolute") ? 'relative':jQuery('body').css('position') ));

			if(options.width != undefined){
				template.css('width', options.width)
			}

			if(options.height != undefined){
				template.find('.p_pad').css('height', options.height)
			}

			if(options.persistant) {
				template.find('.p_cancel').remove();
			}

			template.find('.p_title').html(options.title);
			template.find('.p_pad').html(options.message);

			template.hide();

			jQuery('body').append(template);

			template.css({
				'top':(jQuery('html').height()/2 - template.height()/2),
				'left':(jQuery('html').width()/2 - template.width()/2)
			});

			if(options.css) {
				template.css(options.css);
			}

			template.find('.p_cancel').click(function(e){
				var _self = this;

				jQuery(_self).parents('.popup_tpl').fadeOut('normal', function(){
					jQuery(_self).parents('.popup_tpl').remove();
					if(options.onClose) {
					options.onClose.call(_self, options);
					}
				});
				e.preventDefault();
				e.stopPropagation();
			});
			template.fadeIn('normal', function() {
				if(options.callback) {
					options.callback.call(_self, options);
				}
			});

			return template;
		}
	};

	var configuration = {
		FBAuthPath:null, //Important set this via jQuery.Nodes({'FBAuthPath':'somepath.com'}) cookie is not sendt to server without it
		ajax_page:null
	}

	jQuery.Nodes = function( method ) {
		if(configuration.FBAuthPath == null) {
			configuration.FBAuthPath = Nodes.Router.applicationPrefix() + '/core/FacebookUsers/authenticate.json';
		}

		if (methods[method] ) {
			return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
		} else if ( typeof method === 'object' || ! method ) {
			return methods.init.apply( this, arguments );
		} else {
			jQuery.error( 'Method ' +  method + ' does not exist on jQuery.Nodes' );
		}
	};

})( jQuery );
