/**Tightly coupled with the Report User Interface this file provides most of the function to manage the actions
* when checking rows.  
* This will really just dispatch the actions to various URLs that should handle the requests.
* Since actions vary in functionality and behavior this will also build the list of actions that must be offered to the user based
* on the context of the application (TrailNetwork, Report, Map View, etc).
*/

/**
 * 
*/
function YahooConnectionHelper(url)
{
	this.url = url;
	this.callback = null;

	this.refreshReport = false;
	
	
	/**@return YahooConnectionCallback or any subclass of it that will handle the success or failure.*/
	YahooConnectionHelper.prototype.getCallback = function()
	{
		if(this.callback == null)
		{
			this.callback = new YahooConnectionCallback();
		}
		return this.callback;
	}
	
	
	/**assigns the callback so the default is not used.
	* @param YahooConnectionCallback or subclass that will handle the success and failure.
	*/
	YahooConnectionHelper.prototype.setCallback = function(yahooConnectionCallback)
	{
		this.callback = yahooConnectionCallback;
	}
	
	/**actually sends the asynchronous request.*/
	this.sendRequest =  function()
	{
		YAHOO.util.Connect.asyncRequest('GET',this.url,this.getCallback(),null);
	}
}


/**The default callback that will show a message in an alert popup if any message is set (after construction, but before requesting).
* Consider extending this:
* 
Example:

* function ReportCallback()
{
	//inheritance
	YahooConnectionCallback.apply(this);
	...
*/
function YahooConnectionCallback()
{
		/**optional message that will be displayed using the standard messaging.*/
		this.successMessage = null;
		this.failureMessage = "Unable to complete request";
		
		/**The defualt success function that will display the success message assigned to hear (if any).  The deafult is not to show any message.*/
		YahooConnectionCallback.prototype.success = function(response)
		{ 
		   if(this.successMessage != null)
		   {
		   		this.showMessage(this.successMessage);
		   }
		   else
		   {
		   		var responseHelper = new GoogleXpathHelper(response.responseText);
		   		this.showMessage(responseHelper.evaluateString('string(response/message[1])'));
		   }
		}
			
		YahooConnectionCallback.prototype.failure = function(yahooFailure)
		{  
		 	this.showMessage(this.failureMessage + ": " + yahooFailure.statusText );
		}
		
		YahooConnectionCallback.prototype.setSuccessMessage = function(successMessage)
		{
			this.successMessage = successMessage; 
		}

		YahooConnectionCallback.prototype.setFailureMessage = function(failureMessage)
		{
			this.failureMessage = failureMessage; 
		}
		
		/**The default show message that will alert the user of success or failure per the success or failure function.*/
		YahooConnectionCallback.prototype.showMessage = function(message)
		{
			alert(message);
		}
		this.scope = this;
}//end YahooConnectionCallback
			 

/**specifically designated callback for the yahoo asynchreqest that will work with the reports and message banner.
* Inerits from YahooConnectionCallback, but implements some refreshing and messaging that will only work in the reports section.
*/
function ReportCallback()
{
	//inheritance
	YahooConnectionCallback.apply(this);
	
	/**overriding parent function this will show the message using the message banner.*/
	ReportCallback.prototype.showMessage = function(message)
	{
		messageBanner.setMessage(message);
	}
	
	/**Overriding the default success, this will call the defualt success and then call refreshReport*/
	ReportCallback.prototype.success = function(response)
	{
		//call the super
		YahooConnectionCallback.prototype.success.apply(this,[response]);
		refreshReport();
	}
	
}

//now really make the ReportCallback inherit from connection callback.
ReportCallback.prototype = new YahooConnectionCallback();
ReportCallback.prototype.constructor = ReportCallback;


/**The html select text that is to be assigned to the header and footer for action control .*/
var htmlSelectText;

/**Simple function to render the appropriate selection list depending on the context 
* Currently the action select doesn't change with each request so just keep it.
* Even if it does change it is best to leave it here until the new one can replace it.
*/
function reportActionUpdateSelect()
{
	if(htmlSelectText == null)
	{
	    var htmlSelectUrl = "/trail/report/action/ReportActionsSelectHtml.jspx?isCallerActivitiesOnly=" + isCallerActivitiesOnly();
	    var connection = YAHOO.util.Connect.asyncRequest('GET',htmlSelectUrl,reportActionUpdateSelectCallback,null);
	}
	else
	{
		fillActionSelect();
	}    
}

function fillActionSelect()
{
		    //alert('success' +response.statusText + response.responseText);
	    if(activeReport.type  == LISTINGS_REPORT_TYPE)
	    {
		    var header = document.getElementById('actionSelectHeader');
		    if(header != null)
		    {
		        header.innerHTML = htmlSelectText;
	    	    var footer = document.getElementById('actionSelectFooter');
	    	    footer.innerHTML = htmlSelectText;
		    }
		 }
}

/**the yahoo callback for the request to get the html */
var reportActionUpdateSelectCallback =
{
	success:function(response)
	{ 
		htmlSelectText = response.responseText
	    fillActionSelect();
	    
	},
	
	failure:function(o)
	{  
	    messageBanner.setMessage("Problem loading actions...please refresh your browser");
	}
	
}

/** An object representation of the definition XML as provided from ReportActionsXml.jspx
* @param <string or google XNode> actionGoogleXmlElement the xnode provided 
*/
function ReportAction(actionGoogleXmlElement)
{
	this.helper = new GoogleXpathHelper(actionGoogleXmlElement);
	
	this.getLabel = function()
	{
		return this.helper.evaluateString("string(Label)");
	}
	
	/**The minimum number that must be selected for the action to take place.
	 * @return max number selected...it will return the default if not specifically defined.
	*/
	this.getMinSelectionLimit  = function(numberSelected)
	{
		var requirementsElement = this.helper.evaluateSingleNode("SelectRequirements");
		var min  = 1;
		if(requirementsElement != null)
		{
			var minAttributeValue = requirementsElement.getAttribute('min');
			if(minAttributeValue != null)
			{
				min = minAttributeValue;
			}
		}
		return min;
	}
		/**The maximum number that must be selected for the action to take place.
	 * @return max number selected...it will return the default if not specifically defined.
	*/
	this.getMaxSelectionLimit = function()
	{
		var requirementsElement = this.helper.evaluateSingleNode("SelectRequirements");

		var max  = 10;
		if(requirementsElement != null)
		{
			var maxAttributeValue = requirementsElement.getAttribute('max');
			if(maxAttributeValue != null)
			{
				max = maxAttributeValue;
			}
		}
		return max;
	}
	
	/**Handles the action of selected filters based on the type of action(s) associated with this ReportAction element.
	*  @listFilters is an array of filters that provides the criteria.
	*  @return message appropriate message to display for the action taken.
	*/
	this.handleAction = function(listFilters)
	{
		//build this message based on the criteria and actions that take place.
		//best to keep the format  of "Action " + " Label " + " what really happened ";
		var resultMessage = "";
		var actionElements = this.helper.evaluateNodeSet("Action");
		if(actionElements.length > 1)
		{
			alert('Hey you, developer, we currently support single actions.');
		}
		
		//for each action execute it.  ideally we will support a series of actions (like workflow processor).
 		for(var whichActionElement = 0; whichActionElement < actionElements.length; whichActionElement++)
 		{
 			var actionElement = actionElements[whichActionElement];
 			var actionHelper= new GoogleXpathHelper(actionElement);
 			var actionLabel = this.getLabel();          
 			var type = actionElement.getAttribute('type');
 			switch (type)
 			{
 				case 'view':
					var filtersArray = listFilters.getFilters();
					var pkArray = new Array();
					//get the pks from the filters.
					for(var whichFilter = 0; whichFilter < filtersArray.length; whichFilter++)
					{
						var filter = filtersArray[whichFilter];
						pkArray.push( filter.getValueParts().value);
					}
					
					//now build the url.
					var urlElement = actionHelper.evaluateSingleNode('Url');
					
					var url = actionHelper.evaluateString('string(Url/Href)');
					
					
					var urlType = urlElement.getAttribute('type');
					
					var confirmMessage= actionHelper.evaluateString('string(Confirm)');
					var confirmedContinue = true;
					if(confirmMessage != null && confirmMessage.length > 0)
					{
						confirmedContinue = confirm(confirmMessage);
					}
					//handle the pks for each type of view.
					if(confirmedContinue)
					{
						//used for list types to separate pks.
						dilimeter = actionHelper.evaluateString('string(Url/Dilimeter)');
						resultMessage = actionHelper.evaluateString('string(Message)');
						for(var whichPk = 0; whichPk < pkArray.length; whichPk++)
						{
							var pk = pkArray[whichPk];
							switch(urlType)
							{
								case 'list':
									url += pk;
									//last time around show the url.
									if(whichPk == pkArray.length -1)
									{
											var destinationType = actionHelper.evaluateString('string(Destination/@type)');
											switch(destinationType)
											{
												case 'ajax':
													var yahooConnectionHelper = new YahooConnectionHelper(url);
													var reportCallback = new ReportCallback();
													
													yahooConnectionHelper.setCallback(reportCallback);
													yahooConnectionHelper.sendRequest();
													
												break;
												default:
													showWindow(url);	
											}
											
									}
									else
									{
										//separate the pks with the appropriate dilimiter.
										url += dilimeter;
									}
									
									break;
								case 'separate':
										var urlForPk = url + pk;
										//force the popup if more than one chosen.
										var forcePopup = pkArray.length > 1;
										showWindow(urlForPk,forcePopup);									
									break;
								default:
									alert(urlType + ' not yet handled');
							}//end switch urlType
						}//end for every pk
					}
					else//confirmation declined
					{
						 resultMessage =  actionLabel + " cancelled"; 
					}
					break; //end switch 'view' 
				
 				default:
 					alert(type + " not a supported action type");
 			}//end switch
 		}
		
		return resultMessage;
	}
}
/**The single method that handles all requests to take action on checked boxes.*/
function handleReportActionChosen(actionKey)
{

        var actionElement = reportActionsXmlHelper.getElementById(actionKey);
        var action = new ReportAction(actionElement);
        var numberSelected = listFilters.getNumberOfFilters();
        
        var max = action.getMaxSelectionLimit();
		var meetsSelectionRequirements = numberSelected <= max ; 
		
		var errorMessage;
		
		//check minimums as defined from the 
		if(!meetsSelectionRequirements)
		{
			errorMessage = "You may only select " + max; 
		}
		else
		{
			var min = action.getMinSelectionLimit();
			meetsSelectionRequirements = numberSelected >= min;
			if(!meetsSelectionRequirements)
			{
				errorMessage = "You must select at least " + min;
			}
		}
		
		if(meetsSelectionRequirements)
		{            
  			var message = action.handleAction(listFilters);
  			var helpHref = "http://wiki.motionbased.com/mb/" + action.getLabel();
            messageBanner.setMessage(message,helpHref);
        }
        else
        {
        	messageBanner.setMessage(errorMessage);
        }
    
}

//======================= Report Actions Definitions ======================
/**Simple function to render the appropriate selection list depending on the context */
function loadReportActionsDefintions()
{
    var htmlSelectUrl = "/trail/report/action/ReportActionsXml.jspx?isCallerActivitiesOnly=" + isCallerActivitiesOnly();
    var connection = YAHOO.util.Connect.asyncRequest('GET',htmlSelectUrl,loadReportActionsDefintionsCallback,null);
    
}


/**a google XPath helper object used to work with the xml representing all of the actions.
* @see #loadReportActionsDefintionsCallback
*/
var reportActionsXmlHelper;

/**the yahoo callback for the request to get the html */
var loadReportActionsDefintionsCallback =
{
	success:function(response)
	{ 
			reportActionsXmlHelper  = new GoogleXpathHelper(response.responseText);
	},
	
	failure:function(o)
	{  
	    messageBanner.setMessage("Problem loading actions...please refresh your browser");
	}
}

loadReportActionsDefintions();