

/**
	PageController class
**/
function PageController(xml) {
	var self = this;

	//alert($("Product:has(NumberOfBusinessLocations:contains('Multiple'))", xml).not(":has(IndustryRef[industryID=AT])").length);
	
	//self.numberOfColumns = Constants.NumberOfColumns  // This is the number of columns for the stand alone pcc  
	self.dataMapper = new DataMapper(xml)
	self.userSpecificBehavior = null;
	self.executionContext = new ExecutionContext();
	self.features = self.dataMapper.getFeatures();
	self.productsRecommended = new Array(); 
	self.productsToDisplay = new Array(); 
	// holds all products that match the current user filter criteria
	// the user needs to narrow this down to one product
	self.productsCurrent = new Array();  
	self.productsUserAdded = new Array(new Product(), new Product());
}



//*** Private methods ***//

PageController.prototype._run = function() {
	var self = this;

	self.userSpecificBehavior._run();
}


PageController.prototype._populateFilters = function() {
	var self = this;
	
	/* Platforms */
	var platforms = self.dataMapper.getPlatforms();
	
	$(Constants.PlatformDDL).html('<option value="">-Platform-</option>');
	
	while (platforms.length > 0) {
		var currentPlatform = platforms.shift();
		$(Constants.PlatformDDL).append('<option value="' + currentPlatform.platformID + '" >' + currentPlatform.platformName + '</option>');
	}	
	
	
	/* Number of business locations */
	$(Constants.NumberOfBusinessLocationsDDL).html('<option value="">-Number of business locations-</option>');
	$(Constants.NumberOfBusinessLocationsDDL).append('<option value="Single">Single</option>');
	$(Constants.NumberOfBusinessLocationsDDL).append('<option value="Multiple">Multiple</option>');
	
	
	/* Product and year */
	var products = self.dataMapper.getProducts(new ProductFilter());
	var productHash = new Array();
	var yearHash = new Array();
	
	// Get only unique values
	while (products.length > 0) {
		var currentProduct = products.shift();
		productHash[currentProduct.productName] = "";
		yearHash[currentProduct.year] = "";
	}
	
	// Product name
	$(Constants.ProductNameDDL).html('<option value="">-Products-</option>');
	
	for (productName in productHash) {
		$(Constants.ProductNameDDL).append('<option value="' + productName + '" >' + productName + '</option>');
	}
	
	// Year
	$(Constants.YearDDL).html('<option value="">-Year-</option>');
	
	for (year in yearHash) {
		$(Constants.YearDDL).append('<option value="' + year + '" >' + year + '</option>');
	}
	
	
	/* Industry */
	var industries = self.dataMapper.getIndustries();
	
	$(Constants.IndustryDDL).html('<option value="">-Industry-</option>');
	
	while (industries.length > 0) {
		var currentIndustry = industries.shift();
		$(Constants.IndustryDDL).append('<option value="' + currentIndustry.industryID + '" >' + currentIndustry.industryName + '</option>');
	}	
	
	
	/* Number of users */
	$(Constants.NumberOfUsersDDL).html('<option value="">-Number of users-</option>');
	$(Constants.NumberOfUsersDDL).append('<option value="Single">Single</option>');
	$(Constants.NumberOfUsersDDL).append('<option value="Up to 5">Up to 5</option>');
	$(Constants.NumberOfUsersDDL).append('<option value="Up to 20">Up to 20</option>');
	$(Constants.NumberOfUsersDDL).append('<option value="Up to 25">Up to 25</option>');

	
	
	/* Tell us more about you business */
	$(Constants.TellUsMoreAboutYourBusinessDDL).html('<option value="">-Tell Us More About Your Business-</option>');
	$(Constants.TellUsMoreAboutYourBusinessDDL).append('<option value="HasSalesAndExpenseTracking">I just need to track sales and expenses.</option>');
	$(Constants.TellUsMoreAboutYourBusinessDDL).append('<option value="HasAccoutingAndBusinessMgmtTools">I need more accounting and/or other business management tools.</option>');
}


PageController.prototype._drawProductFeatureTable = function(features, products) {
	var self = this;

	self._initProductFeatureTable(products);

	
	/* Product headers */
	self.userSpecificBehavior._drawProductHeaders(products);


	/* Feature rows */
	for (var y = 0; y < features.length; y++) {
		var feature = features[y];
			
		self._drawRow( feature, products, self._isFeatureGroupRow(features, y, feature), self._isLastFeatureRowInFeatureGroup(features, y, feature) );
	}
}


PageController.prototype._initProductFeatureTable = function(products) {
	var self = this;
	var jqTable = jQueryUtility.GetJQObject("#" + Constants.ID_ProductFeatureTable);

	// Redraw the product feature table - set the first column of the thead.  This also includes the thead element
	$(jqTable).html( Template.replaceKeyFeaturesClass(Constants.HTML_ProductHeaderItemFirst, products) );
}


PageController.prototype._drawRow = function(feature, products, isFeatureGroupRow, isLastFeatureRowInFeatureGroup) {
	var self = this;
	
	if (isFeatureGroupRow) {
		self._drawFeatureGroupRow(feature, products);

		// Wire up feature group expander
		$('#' + feature.featureGroup.featureGroupID).click( 
			function() { PageController.instance.expandCollapseFeatureGroup(feature, null); return false; } 
		)    
	}
	
	self._drawFeatureRow(feature, products, isLastFeatureRowInFeatureGroup);

	// Wire up feature expander
	$('#' + feature.featureGroup.featureGroupID + Constants.ConcatString + feature.featureID + " td:first").click( 
		function() { PageController.instance.expandCollapseFeature(feature, null); return false; } 
	)    
}


PageController.prototype._isFeatureGroupRow = function(features, index, feature) {
	var self = this;
	
	return index == 0 || features[index-1].featureGroupID != feature.featureGroupID
}


PageController.prototype._isLastFeatureRowInFeatureGroup = function(features, index, feature) {
	var self = this;

	// Catch first row, which is always a feature group row
	if (index == 0)
		return false;

	// Catch last feature row of the last feature group row.  This one does not get the a class.
	if (features.length - 1 == index)
		return false;
	
	return features[index+1].featureGroupID != feature.featureGroupID;
}


PageController.prototype._drawFeatureGroupRow = function(feature, products) {
	var self = this;
	
	var htmlRow = Constants.HTML_FeatureGroupRowOpen;
	
	htmlRow = Template.processFeatureGroupRowTemplate(htmlRow, feature.featureGroup, products);
	
	self._appendFeatureRow(htmlRow);
}


PageController.prototype._drawFeatureGroupCell = function(featureGroup, product, template) {
	var self = this;
	
	return template;
}


PageController.prototype._drawFeatureRow = function(feature, products, isLastFeatureRowInFeatureGroup) {
	var self = this;

	var htmlRow = Constants.HTML_FeatureRowOpenTr;

	// The last feature row under a feature group has an additional class
	if (isLastFeatureRowInFeatureGroup) {
		htmlRow = Constants.HTML_FeatureRowOpenLastTr;
	}

	htmlRow += Constants.HTML_FeatureRowFirst
	
	// Product columns
	for (var i = 0; i < self._getProductColumnCount(); i++) {
		
		// Middle columns
		var featureCellTemplate = Constants.HTML_FeatureItemMiddle
		
		// Last column
		if (i + 1 == self._getProductColumnCount()) {
			featureCellTemplate = Constants.HTML_FeatureItemLast;
		}

		htmlRow += self._drawFeatureCell(feature, products[i], featureCellTemplate);
	}
	
	htmlRow += Constants.HTML_FeatureRowClose;

	htmlRow = Template.processFeatureRowTemplate(htmlRow, feature);
	
	self._appendFeatureRow(htmlRow);
	
	// Wire up popups
	for (var i = 0; i < products.length; i++) {

		if (products[i].hasFeature(feature)) {
			var featureScreenShotLinkID = Constants.TPL_ITEM_ProductFeatureID;

			featureScreenShotLinkID = Template.replaceProductID(featureScreenShotLinkID, products[i]);
			featureScreenShotLinkID = Template.replaceFeatureID(featureScreenShotLinkID, feature);

			// *** Call to thickbox.js ***/
			tb_init($('#' + featureScreenShotLinkID));
		}
	}  
}


PageController.prototype._drawFeatureCell = function(feature, product, template) {
	var self = this;
		
	return Template.processProductFeatureCellTemplate(template, product, feature);
}


PageController.prototype._appendFeatureRow = function(html) {
	var self = this;
	var jqTable = jQueryUtility.GetJQObject("#" + Constants.ID_ProductFeatureTable);

	jqTable.append(html);
}


PageController.prototype._hideFeatureRow= function(featureElmt) {
	var self = this;
	
	featureElmt.hide();
}


PageController.prototype._showFeatureRow= function(featureElmt) {
	var self = this;
	
	featureElmt.show();
}


PageController.prototype._drawTitleRow= function() {
	var self = this;
	
	$(Constants.CurrentUserTitleRow).removeClass("hide");
	$(Constants.NewUserTitleRow).removeClass("hide");
	
	if (self.executionContext.userType == Constants.CurrentUserType) {
		$(Constants.NewUserTitleRow).addClass("hide");
	}
	else if (self.executionContext.userType == Constants.NewUserType) {
		$(Constants.CurrentUserTitleRow).addClass("hide");
	}
}


PageController.prototype._hideAllProductFilters = function() {
	var self = this;
	
	$("#divPlatforms").addClass("hide");
	$("#divNumberOfBusinessLocations").addClass("hide");
	$("#divProduct").addClass("hide");
	$("#divYear").addClass("hide");
	$("#divIndustries").addClass("hide");	
	$("#divNumberOfUsers").addClass("hide");
	$("#divTellUsMoreAboutYourBusiness").addClass("hide");
	$("#divPlatforms").addClass("hide");
}


PageController.prototype._getProductColumnCount = function() {
	var self = this;
	
	return self.productsToDisplay.length;
}


//*** Public methods ***//

PageController.createInstance = function(xml, controllerType) {
	var pc = new PageController(xml);
	
	if (controllerType == "productpage") {
		
		pc.userSpecificBehavior = new ProductPageBehavior(pc) ;
	} 
	else {
		pc.userSpecificBehavior = new NewUserBehavior(pc);
	}
	
	PageController.instance = pc;
}


PageController.setSendEmailLink = function() {
	var url = document.location;
	
	$("#emailPage").attr("href", "mailto:&subject=Quickbooks Comparison Chart&body=" + url);
	
}


PageController.prototype.drawUI = function(productID,  industryID) {
	var self = this;
	
	// delegate
	// We keep this method to simplify the external interface used in the .html page
	self.userSpecificBehavior.drawUI(productID,  industryID);
}


PageController.prototype.expandCollapseFeature= function(feature, displayMode) {
	var self = this;
	var jqFeatureRow;
	var jqFeatureDivs;
	var action = "";

	jqFeatureRow = $("#" + feature.featureGroupID +  Constants.ConcatString + feature.featureID);
	jqFeatureDivs = $("div", jqFeatureRow);
	jqFeatureDescriptionCell = $(jqFeatureRow).children('td.description');

	//alert($(jqFeatureDivs[0]).attr('style'));


	/* Figure out the action */	
	if (displayMode == "collapse") {
		action = "expand"
	}
	else if (displayMode == "expand") {
		action = "collapse"
	}
	// toggle
	else {
		action = $(jqFeatureDivs[0]).attr('style').match('none') ? "expand" : "collapse";
	}


	/* Set expander visibility */
	if (action == "expand") {
		jqFeatureRow.addClass('expanded');
		jqFeatureDescriptionCell.addClass('info');
		jqFeatureDivs.show();
	} 
	else if (action == "collapse") {
		jqFeatureRow.removeClass('expanded');
		jqFeatureDescriptionCell.removeClass('info');
		jqFeatureDivs.hide();
	}
	else {
		throw new Error("Invalid expander operation.");
	}
}


PageController.prototype.expandCollapseFeatureGroup= function(feature, displayMode) {
	var self = this;
	var jqExpanderIcons;
	var action = "";
	
	// This should hold 2 images one in first and one in the last column
	jqExpanderIcons = $('#' + feature.featureGroupID + " img");
	

	/* Figure out the action */	
	if (displayMode == "collapse") {
		action = "expand"
	}
	else if (displayMode == "expand") {
		action = "collapse"
	}
	// toggle
	else {
		// Note the src attribute is as follows between browsers:
		// IE: full path
		// FF: relative path
		// Therfore we need to look for the substring of the relative path defined in Constants.FeatureGroupCollapsedImgFirst
		action = $(jqExpanderIcons[0]).attr('src').match(Constants.FeatureGroupCollapsedImgFirst) ? "expand" : "collapse";
	}
	

	/* Change icons */
	if (action == "expand") {
		$(jqExpanderIcons[0]).attr('src', Constants.FeatureGroupExpandedImgFirst);
		$(jqExpanderIcons[1]).attr('src', Constants.FeatureGroupExpandedImgLast);
	} 
	else if (action == "collapse") {
		$(jqExpanderIcons[0]).attr('src', Constants.FeatureGroupCollapsedImgFirst);
		$(jqExpanderIcons[1]).attr('src', Constants.FeatureGroupCollapsedImgLast);
	}
	else {
		throw new Error("Invalid expander operation.");
	}
	
	
	/* Hide feature rows for the specific feature group */
	// Feature rows have an id value of featureGroupID + Constants.ConcatString + featureID
	var jqFeatureRows = $("tr[id^='" + feature.featureGroupID +  Constants.ConcatString + "']");
	
	jqFeatureRows.each(function() {
		if (action == "collapse") {
			self._hideFeatureRow($(this));
		}
		else {
			self._showFeatureRow($(this));
		}
	});
}


PageController.prototype.moveProductFirst = function(productID) {  
	var self = this;
	var productsReordered = new Array();
	
	for (var i = 0; i < self._getProductColumnCount(); i++) {
		if (self.productsToDisplay[i].productID == productID) {
			productsReordered.unshift(self.productsToDisplay[i]);
		}
		else {
			productsReordered.push(self.productsToDisplay[i]);
		}
	}
	
	self.productsToDisplay = productsReordered;
	self.drawUI();
}


PageController.prototype.removeProduct = function(productID) {  
	var self = this;
	
	// Remove product from productsToDisplay
	for (var i = 0; i < self.productsToDisplay.length; i++) {
		if (self.productsToDisplay[i].productID == productID) {
			self.productsToDisplay.splice(i, 1);
		}
	}
	
	// Remove product from productsUserAdded - set it to a null product
	for (var i = 0; i < self.productsUserAdded.length; i++) {
		if (self.productsUserAdded[i].productID == productID) {
			self.productsUserAdded[i] = new Product();
		}
	}

	self.drawUI();
}


PageController.prototype.resetProductFilter = function() {  
	var self = this;
	
	$(Constants.PlatformDDL).get(0).selectedIndex = 0;
	$(Constants.NumberOfBusinessLocationsDDL).get(0).selectedIndex = 0;
	$(Constants.ProductNameDDL).get(0).selectedIndex = 0;
	$(Constants.YearDDL).get(0).selectedIndex = 0;
	$(Constants.NumberOfUsersDDL).get(0).selectedIndex = 0;
	$(Constants.IndustryDDL).get(0).selectedIndex = 0;
	$(Constants.TellUsMoreAboutYourBusinessDDL).get(0).selectedIndex = 0;

	self.drawUI(true);
}


PageController.prototype.selectUserType = function(userType) {  
	var self = this;
	
	$(Constants.CurrentUserTab).removeClass();
	$(Constants.NewUserTab).removeClass();
	
	if (userType == "current") {
		$(Constants.CurrentUserTab).addClass("selected");
		self.executionContext.userType = Constants.CurrentUserType;
		self.userSpecificBehavior = new CurrentUserBehavior(this);
	}
	else if (userType == "new") {
		$(Constants.NewUserTab).addClass("selected");
		self.executionContext.userType = Constants.NewUserType;
		self.userSpecificBehavior = new NewUserBehavior(this);
		$(Constants.ProductsUserAddDDL + "4").remove();
		$(Constants.ProductsUserAddDDL + "5").remove();
	}

	self.drawUI(true);
}