// need to detect IE.  IE can't transition properly if a div
// uses position tag.  
var isIE = navigator.appName.indexOf("Microsoft") != -1;

/**
 * RSS JavaScript
 *
 * This file makes use of JQuery and SynAjax.  Both should be included along with
 * this file.
 */ 
Syn.RSS = Syn.Component.extend(
{
	/**
	 * URL to the RSS Ajax API
	 *
	 * @var string
	 */
	ajax_api_url: Syn.Config.PortalRoot + 'rss/rss_api.php',

	/**
	 * Has the customize menu been loaded into the DOM yet?
	 *
	 * @var bool
	 */
	customize_loaded: false,

	/**
	 * List of ids from a previous submit attempt
	 * This variable is used to help prevent a form from being submitted more than once.
	 *
	 * @var string
	 */
	prev_feed_ids: -1,

	/**
	 * Max feeds per user allowed.
	 *
	 * This will only be used to display to the user when too many feeds have been selected.
	 *
	 * @var int
	 */
	max_feeds_per_user: 20,
			
	/**
	 * Page 
	 *
	 * @var int
	 */
	page: 0,
	
	
	/**
	 * Zone
	 * @var int
	 */
	zone: 0,
	
	
	/**
	 * Position
	 * @var int
	 */
	pos: 0,
	
	/**
	 * Tag - type of rss feeds like default, music or entertainment etc... 
	 * @var string
	 */
	tag: '',
	
	/**
	 * Regions - geography like local or national 
	 * @var string
	 */
	regions: '',
	
	/**
	 * Indicates if logged in or not 
	 * @var int
	 */
	logged_in: 0,
	
	
	/**
	 * Indicates if there is an alternate login page
	 * @var string
	 */
	alt_login_page: '',
	

	/**
	 * Is the login disabled?
	 *
	 * This will be disabled between the period from a login submit until a status is returned.
	 *
	 * @var int
	 */
	login_disabled: false,
	
	init: function(config)
	{	
		this._super(config);
		this.page = config.page;		
		this.zone = config.zone;
		this.pos = config.pos;
		this.tag = config.tag;
		this.logged_in = config.logged_in;
		this.regions = config.regions;	
		this.alt_login_page = config.alt_login_page;
		this.login_disabled = config.login_disabled;
		this.max_feeds_per_user = parseFloat(config.max_feeds_per_user);
	
		var self = this;

		this.connectRssClick();
	
	},
	
	/**
	 * Late binding connect to the rss_form submit button.
	 *
	 * This binding "connection" cannot be made until after the object is rendered 
	 */
	connectNewElements: function()
	{
		this.uniqueElmt("feeds_form").connect("submit", this, "saveFeeds");
		this.uniqueElmt("lrf_container").find(".rss_cancel").connect("click", this, "toggleCustomize", []);
	},

	/**
	 * Connect to the rss_form submit / cancel button.
	 *
	 * Handles alternate login page by setting a new button location 
	 */
	connectRssClick: function()
	{
		this.uniqueElmt("login_form").connect("submit", this, "login");
		var rss_container = this.uniqueElmt("lrf_container"); 
		rss_container.find(".local_cancel").connect("click", this, "toggleCustomize", []);	
		
		rss_container.find(".rss_remove").connect("click", this, "remove");

		if (this.logged_in == 0)
		{
		if (this.login_disabled)
	        {
	        	if (this.alt_login_page)
			{
				var alt_login_page = this.alt_login_page;
				rss_container.find(".rss_click").bind("click", function()
			{
				window.location = alt_login_page;
				return false;
				});
			}
			else
			{
				rss_container.find(".rss_click").wrap('<span>');
				rss_container.find(".rss_click").each(function(i, obj)
			{
					var text = $(obj).html();
					$(obj).parent().html(text);
				});
			}
		}
		else
		{
			rss_container.find(".rss_click").connect("click", this, "showLogin", []);
		}
		}
		else
		{
			rss_container.find(".rss_click").connect("click", this, "toggleCustomize", []);			
		}
	},

	/**
	 * Reset attributes.
	 *
	 * The attributes will need to be reset when the entire component is reloaded.
	 * This will happen after a successful login or a successful saving of the feeds.
	 */
	reset: function()
	{
		this.prev_feed_ids = -1;
		this.customize_loaded = false;
	},

	/**
	 * Display the login form.
	 */
	showLogin: function()
	{
		this.uniqueElmt("lrf_customize_link").addClass('local_nav_up');		
		this.uniqueElmt("lrf_login_form").slideDown('slow');
	},

	/**
	 * Attempt to login.
	 *
	 * This function will make an Ajax request to try to login.
	 */
	login: function()
	{	
		if (!this.loginDisabled)
		{	
			var username = this.uniqueElmt("lrf_username").val();			
			var password = this.uniqueElmt("lrf_password").val();
			
			this.displayError();
			this.indicateLogin('start');
			
			$.ajax(
			{
				url: this.ajax_api_url,
				self: this,
				login: 1,
				failMessage: 'The username and/or password is incorrect',
				type: 'POST',
				dataType: 'text',
				complete: this.checkResponse,
				data: 'rss=1&action=login&u=' + encodeURIComponent(username) +
					'&p=' + encodeURIComponent(password) + '&page=' + encodeURIComponent(this.page) + '&pos=' + encodeURIComponent(this.pos) + '&zone=' + encodeURIComponent(this.zone) + '&tag=' + encodeURIComponent(this.tag)	+ '&rid=' + this.getRandomId()
			});
			
		}
	},
	
	/**
	 * Remove a feed.
	 *
	 * This function will make an Ajax request to try ad remove a feed.
	 */
	remove: function(element)
	{		
	    var elem = $(element).attr("title");
	    var id = elem.match(/[a-z0-9,]+$/);	
	    
		var self = this;	    		
		
		$(element).parent().parent().slideUp("normal", function() {
    
		$.ajax(
		{
			url: self.ajax_api_url,
			self: self,
			type: 'GET',
			dataType: 'text',
			complete: self.removeComplete,
			data: 'rss=1&action=remove&value=' + encodeURIComponent(id) + '&page=' + encodeURIComponent(self.page) + '&pos=' + encodeURIComponent(self.pos) + '&zone=' + encodeURIComponent(self.zone) + '&tag=' + encodeURIComponent(self.tag) + '&rid=' + self.getRandomId(),
			element: $(this)
		});

    
		});

	},

	/**
	 * This handles the hiding and showing of deleted items 
	 *
	 * If the remove was successful remove the container
	 * otherwise show what was originally there.
	 *
	 * @param {Function} callback
	 */
	removeComplete: function(req, status)
	{
		if (req.responseText == 1)
		{
			var rss_region = this.element.parent();
			this.element.remove();
			var curClass = this.self;
	
			if (rss_region.find('.lrf_feed').size() == 0)
			{
				rss_region.slideUp("normal", function()
			{
				$(this).remove();
	
				if (curClass.uniqueElmt("lrf_region").size() == 0)
				{
					curClass.uniqueElmt("lrf_inst").slideDown("slow");
				}
	
			});
		}
	
		}
		else
		{
			this.element.slideDown();
		}    
	},
	
	

	/**
	 * Toggle the customization menu.
	 *
	 * If the customization menu hasn't been loaded yet, we will make an ajax call
	 * to load the menu.  We do this to save precious database resources as we
	 * don't want to pull in all the available feeds to select from if the
	 * user doesn't want to make any modifications.
	 *
	 * @param {Function} callback
	 */
	toggleCustomize: function(callback)
	{	
		if (!this.customize_loaded)
		{			
			this.indicateCustomize('start');
			this.customize_loaded = true;
		
			$.ajax({
				callback: callback,
				complete: this.toggleCustomizeComplete,
				self: this,
				type: 'POST',
				dataType: 'text',
				url: this.ajax_api_url,
				data: 'rss=1&action=customize&page=' + encodeURIComponent(this.page) + '&pos=' + encodeURIComponent(this.pos) + '&zone=' + encodeURIComponent(this.zone) + '&tag=' + encodeURIComponent(this.tag) + '&regions=' + encodeURIComponent(this.regions) + '&rid=' + this.getRandomId(),
				page: this.page,
				pos: this.pos,
				zone: this.zone


			});	            	
		}
		else
		{
			this.toggleCustomizeComplete(false, false, callback);
		}
		
	},

	/**
	 * Toggle the customization menu (complete).
	 *
	 * This will be called once the data is present in the lrf_edit div.
	 *
	 * @param {Resource} req
	 * @param {Function} callback
	 */
	toggleCustomizeComplete: function(req, status, callback)
	{
		var self = 0;
		if (req)
		{
			self = this.self;
			this.self.indicateCustomize('finished');
			self.uniqueElmt("lrf_edit").html(req.responseText); 
     			self.connectNewElements();
		}
		else
		{
			self = this;
		}			

		callback = this.callback ? this.callback : callback;
		self.uniqueElmt("lrf_edit").slideToggle('slow', callback);	

				
		if (self.uniqueElmt("lrf_customize_link").hasClass('local_nav_up'))
		{
			self.uniqueElmt("lrf_customize_link").removeClass('local_nav_up');
		}
		else		
		{
			self.uniqueElmt("lrf_customize_link").addClass('local_nav_up');
		}
		
		
	},

	/**
	 * Attempt to save the selected feeds.
	 *
	 * This function will make an Ajax request
	 * to attempt to save the selected feeds.
	 *
	 * @param {Object} form
	 */
	saveFeeds: function(form)
	{	
		var feed_ids = '';		
		var input_elements = form.getElementsByTagName('input');
		var selections = Array();
		
		for (i=0; i<input_elements.length; i++)
		{
			if (input_elements[i].type == 'checkbox' && input_elements[i].checked)
			{				
				if (selections[input_elements[i].name] === undefined)
				{
					selections[input_elements[i].name] = '';
				}
				selections[input_elements[i].name] += input_elements[i].value + ',';
					
			}			

		}
        
	    for (key in selections)
		{
			feed_ids += key + '=' + selections[key] + '|';
	    } 	    
	    var strlen = feed_ids.length;
	    
		feed_ids = feed_ids.slice(0,strlen-2); 
	    feed_ids = feed_ids.replace(",|", "|");
	
		if (this.prev_feed_ids != feed_ids)
		{			
			this.prev_feed_ids = feed_ids;
			this.displayError();
	
			this.indicateSave('start');

			$.ajax(
			{
				url: this.ajax_api_url,
				self: this,
				saveFeeds: true,
				failMessage: 'A maximum of ' + this.max_feeds_per_user + ' RSS feed selections is allowed.',
				type: 'POST',
				dataType: 'text',
				complete: this.checkResponse,
				data: 'rss=1&action=save&value=' + encodeURIComponent(feed_ids) + '&page=' + encodeURIComponent(this.page) + '&pos=' + encodeURIComponent(this.pos) + '&zone=' + encodeURIComponent(this.zone) + '&tag=' + encodeURIComponent(this.tag)	+ '&regions=' + encodeURIComponent(this.regions) + '&rid=' + this.getRandomId()	    
			    
			});


			
		}

	},	

	/**
	 * Response checker function.
	 *
	 * This function will be responsible for checking the status of a recent
	 * Ajax request.  If the first character returned is 0 then there was a failure
	 * otherwise it was a success.
	 *
	 * @param {Resource} req
	 */
	checkResponse: function(req)
	{
		//The first character echoed back is a status of 0 or 1
		var response = parseFloat(req.responseText.substr(0, 3));

		//Everything after the char above	
		var component = req.responseText.substr(3);	
		var error_msg = this.failMessage ? this.failMessage : 'An error has occurred';

		if (this.login)
		{
			this.self.indicateLogin('finished');
		}

		if (!response)
		{	
			if (this.saveFeeds)
			{
				this.self.indicateSave('finished');
			}
			this.self.displayError(error_msg);
		}
		else
		{
			if (this.saveFeeds)
			{
				var self = this.self;

				// As mentioned earlier, IE has can't properly display
				// jQuery animations when a position has been set to anything
				// other than static.  So the IE users will have to miss out
				// on the loading overlay from rolling up with the save.
				// IE will still see the overlay, it just won't animate
				// like it will in a non-IE browser.
				if (isIE)
				{
					self.indicateSave('finished');	
				}

				this.self.toggleCustomize(function()
				{
					if (!isIE)
					{
						self.indicateSave('finished');						
					}
					self.replaceContent(component);
					
				});
			}
			else
			{
				this.self.logged_in = 1;
				this.self.replaceContent(component);	
			}
			this.self.reset();
		}
	},

	/**
	 * Show or hide an indicator for trying to log in
	 *
	 * @param {String} what What action is taking place
	 */
	indicateLogin: function(what)
	{
		var cover = this.uniqueElmt("lrf_cover_login");
		var indicator = this.uniqueElmt("lrf_indicator_login");
		
		switch(what)
		{
			case 'start':
				this.loginDisabled = true;
				this.uniqueElmt('lrf_username').attr('disabled', true);
				this.uniqueElmt('lrf_password').attr('disabled', true);				
				indicator.parent().css('position', 'relative');
				width = indicator.parent().innerWidth();
				height = indicator.parent().innerHeight();
				cover.css('width', width + 'px');
				cover.css('height', height + 'px');	
				
				cover.css('display', 'block');
				indicator.css('top', (height/2-indicator.height()/2));
				indicator.css('left', (width/2-indicator.width()/2));
				indicator.css('visibility', 'visible');
				
				break;

			case 'finished':
				this.loginDisabled = false;
				this.uniqueElmt('lrf_username').attr("disabled", false);	
				this.uniqueElmt('lrf_password').attr("disabled", false);			
				cover.css('display', 'none');			
				indicator.css('visiblity', 'hidden');			
				indicator.parent().css('position', 'static');
				
				break; 
		}
	},

	/**
	 * Show or hide an indicator for saving the customize menu
	 *
	 * @param {String} what What action is taking place
	 */
	indicateSave: function(what)
	{
		var cover = this.uniqueElmt("lrf_cover_save");
		var indicator = this.uniqueElmt("lrf_indicator_save");
	
		switch(what)
		{
			case 'start':	
				indicator.parent().css("position", "relative");
				width = indicator.parent().width();
				height = indicator.parent().height();
				
				cover.css('width', width + 'px');
				cover.css('height', height + 'px');
				
				cover.css('display', 'block');
				indicator.css('top', (height/2-indicator.height()/2) + 'px');
				indicator.css('left', (width/2-indicator.width()/2) + 'px');
								
				indicator.css('visibility', 'visible');				
				
				break;

			case 'finished':	
				cover.css('display', 'none');
				indicator.css('visibility', 'hidden');
				indicator.parent().css('position', 'static');
				
				break; 
		}
	},

	/**
	 * Show or hide an indicator for loading the customize menu
	 *
	 * @param {String} what What action is taking place
	 */
	indicateCustomize: function(what)
	{	
		switch(what)
		{
			case 'start':
				this.uniqueElmt("lrf_indicator_customize").show();
				break;

			case 'finished':
				this.uniqueElmt("lrf_indicator_customize").hide();
				break; 
		}
	},

	/**
	 * Replace content in a container.
	 *
	 * @param {String} content
	 */
	replaceContent: function(content)
	{ 
		this.uniqueElmt('lrf_container').get(0).innerHTML = content;
		this.connectRssClick();
	},

	/**
	 * Display an error message (or not)
	 *
	 * If msg is not supplied then the error message will be hidden.
	 *
	 * @param {String} msg [optional]
	 */
	displayError: function(msg)
	{
		var lrf_error = this.uniqueElmt("lrf_error");

		if (msg)
		{
		this.uniqueElmt("lrf_container").find(".lrf_error").html(msg).show();           
		}
		else
		{
			this.uniqueElmt("lrf_container").find(".lrf_error").hide().html('');
		}

	},


	/**
	 * Sets the max feed per user allowed.
	 *
	 * @param {Int} max
	 */
	setMaxFeedsPerUser: function(max)
	{
		this.max_feeds_per_user = max;
	},
	
	
	/**
	 * Creates a reandom id to prevent caching.
	 */
	getRandomId: function()
	{
		return new String(Math.random()).match(/\d+$/);	
	}
	
	
	
}
);
