﻿// namespace atlas
var atlas = atlas || {};

// class BenchmarkTool
atlas.BenchmarkTool = function(indicatorSelectorNamespace, locationSelector1Namespace, locationSelector2Namespace) {

	// copy for closure
	var self = this;

	//// Private member vars ////
	var _locationSelector1 = new atlas.LocationSelector(locationSelector1Namespace);
	var _locationSelector2 = new atlas.LocationSelector(locationSelector2Namespace);
	var _loadingIndicator = new atlas.LoadingIndicator("/images/loading-spinner-arrows.gif", "Loading...");

	/**
	* Config container for keeping track of the user's selections
	*/
	var _benchmarkToolConfig;

	/**
	* Keeps track of the currently visible wizard page. Starts counting from 1 (as opposed to 0)
	*/
	var _currentPage = 1;

	/**
	* The total number of pages in the wizard
	*/
	var _totalPages = 3;

	//// Private member functions ////	
	/**
	* Hides all wizard pages
	*/
	this.hideAllPages = function() {
		var $pages = $("div[id^='wizard-page-']");
		if (!$pages) {
			return;
		}
		$pages.each(function(index, element) {
			$(element).hide();
		});
	};

	/**
	* Updates the page to the specified number.
	*/
	this.setCurrentPage = function(pageNumber) {
		_currentPage = pageNumber;
		if (_currentPage == 1) {
			$("#btnBack").hide();
		}
		else {
			$("#btnBack").show();
		}
		if (_currentPage == _totalPages) {
			$("#btnNext").hide();
			$("#btnComplete").show();
		}
		else {
			$("#btnNext").show();
			$("#btnComplete").hide();
		}
	};

	/**
	* Displays a message to the user
	*/
	this.displayMessage = function(message) {
		alert(message);
	};

	/**
	* Disables all buttons
	*/
	this.disableButtons = function() {
		$("#btnBack").attr('disabled', 'disabled');
		$("#btnNext").attr('disabled', 'disabled');
		$("#btnStartOver").attr('disabled', 'disabled');
	};

	/**
	* Enables all buttons
	*/
	this.enableButtons = function() {
		$("#btnBack").removeAttr('disabled');
		$("#btnNext").removeAttr('disabled');
		$("#btnStartOver").removeAttr('disabled');
	};

	/**
	* Processes the selections on page one and moves to the next page
	*/
	this.finishPageOne = function() {
		//collect the currently selected indicator ids
		var indIds = getIndicatorSelector(indicatorSelectorNamespace).getSelectedIndicatorIds();
		if (indIds.length == 0) {
			self.displayMessage("Please select at least one indicator.");
			return false;
		}

		//configure the location selector to only show locations with data for
		//these indicators, then proceed to the next page
		_loadingIndicator.show();
		self.disableButtons();
		self.initializePageTwo(indIds, function() {
			//re-enable everything and move to the next page
			_loadingIndicator.hide();
			self.enableButtons();
			pub.showNextPage();
		});
	};

	this.initializePageTwo = function(indicatorIds, onCompleteCallback) {

		_locationSelector1.setAvailableLocationTypesByIndicator(indicatorIds, function() {

			//the selector will have loaded up all available types with data, but certain types 
			//shouldn't be available for this tool, such as "Nation" or "PCSA", so remove them
			var blacklist = ["Nation", "Primary Care Service Area"];
			var locTypes = _locationSelector1.getAvailableLocationTypes();
			var newLocTypes = [];
			$(locTypes).each(function(index, locType) {
				if ($.inArray(locType.name, blacklist) > -1) {
					return;
				}
				newLocTypes.push(locType);
			});
			_locationSelector1.setAvailableLocationTypes(newLocTypes);

			if (onCompleteCallback) {
				onCompleteCallback();
			}
		}, false);
	};

	/**
	* Processes the selections on page two and moves to the next page
	*/
	this.finishPageTwo = function() {

		//ensure we have at least one location selected
		var locationList = _locationSelector1.getSelectedLocations();
		if (locationList.length == 0) {
			this.displayMessage("Please select at least one location.");
			return;
		}

		//save off the list of selected locations in our benchmark tool config
		_benchmarkToolConfig.locations = locationList;

		//configure the location selector to only show certain location types
		self.initializePageThree();

		pub.showNextPage();
	};

	this.initializePageThree = function() {
		var types = self.getTypesForBenchmarkLocation();
		_locationSelector2.setAvailableLocationTypes(types);
	};

	/**
	* Returns a list of location types that should be available to select 
	* as a benchmark region based on the selections of comparison regions
	*/
	this.getTypesForBenchmarkLocation = function() {
		// The types available to select from for the benchmark location must
		// 1. Have data for the selected indicators
		// 2. Match the rules specified by Dartmouth in the PLS
		var typesWithData = _locationSelector1.getAvailableLocationTypes();
		var currentType = _locationSelector1.getCurrentLocationType();

		//these rules are described in the PLS
		var ids = [];
		switch (currentType.id) {
			case locationTypeIds.stateId:
				ids = [locationTypeIds.stateId,
						locationTypeIds.nationId];
				break;

			case locationTypeIds.hospitalId:
				ids = [locationTypeIds.hospitalId,
						locationTypeIds.hrrId,
						locationTypeIds.stateId,
						locationTypeIds.nationId];
				break;

			case locationTypeIds.hsaId:
				ids = [locationTypeIds.hsaId,
						locationTypeIds.hrrId,
						locationTypeIds.stateId,
						locationTypeIds.nationId];
				break;

			case locationTypeIds.hrrId:
				ids = [locationTypeIds.hrrId,
						locationTypeIds.stateId,
						locationTypeIds.nationId];
				break;

			case locationTypeIds.countyId:
				ids = [locationTypeIds.countyId,
						locationTypeIds.stateId,
						locationTypeIds.nationId];
				break;
		}

		var typesForBenchmark = [];
		$(typesWithData).each(function(index, type) {
			if ($.inArray(type.id, ids) > -1) {
				typesForBenchmark.push(type);
			}
		});
		return typesForBenchmark;
	};

	/**
	* Processes the selections on page two and moves to the next page
	*/
	this.finishPageThree = function() {
		//ensure we have exactly one location selected
		var locationList = _locationSelector2.getSelectedLocations();
		if (locationList.length != 1) {
			this.displayMessage("Please select a single benchmark location.");
			return;
		}

		//save off the selected location to our benchmark tool config
		_benchmarkToolConfig.benchmarkLocation = locationList[0];

		//create a query string out of our benchmark tool config and redirect
		var url = $(document).url().attr("path") + "?" + _benchmarkToolConfig.toQueryString();
		//use regular commas, not encoded ones
		url = url.replace(/%2C/gi, ",");
		window.location = url;
	};

	/**
	* Loads configuration from the query string and fills-out the previously selected options in the wizard
	*/
	this.loadConfiguration = function() {
		var indicatorsLoaded = false;
		var locationsLoaded = false;
		_benchmarkToolConfig = atlas.BenchmarkToolConfig.parseQueryString($(document).url().attr("query"),
			function() { //onContainerLoadComplete
				getIndicatorSelector(indicatorSelectorNamespace).updateSelectedIndicators();
				indicatorsLoaded = true;
				loadLocationSelectorTrees();
			},
			function() { //onLocationsLoadComplete
				for (var i = 0; i < _benchmarkToolConfig.locations.length; i++) {
					var location = _benchmarkToolConfig.locations[i];
					_locationSelector1.addSelectedLocation(location.id, location.name, location.typeId, location.type);
				}
				locationsLoaded = true;
				loadLocationSelectorTrees();
			},
			function() { //onBenchmarkLocationLoadComplete
				var location = _benchmarkToolConfig.benchmarkLocation;
				_locationSelector2.addSelectedLocation(location.id, location.name, location.typeId, location.type);
			}
		);

		function loadLocationSelectorTrees() {
			//both the previously selected indicators and the locations must be loaded before the location trees can be loaded
			if (indicatorsLoaded && locationsLoaded) {
				//Trigger loading of the tree on the 2nd page. 
				var indIds = getIndicatorSelector(indicatorSelectorNamespace).getSelectedIndicatorIds();
				self.initializePageTwo(indIds, function() {
					//trigger loading of the tree on the last page 
					//(which is dependant on page 2's selected locations and selected location type)
					self.initializePageThree();
				});
			}
		}
	}

	//// Public variables & methods ////
	var pub = {

		/** 
		* Returns true if the BenchmarkTool has been configured with all the necessary 
		* information to display a report
		*/
		isConfigured: function() {
			return _benchmarkToolConfig.isConfigured();
		},

		/** 
		* Shows the wizard starting at page 1
		*/
		startWizard: function() {
			this.showPage(1);
			$("#start-wizard").click();
		},

		/** 
		* Shows the specified page 
		*/
		showPage: function(pageNumber) {
			var pageId = "wizard-page-" + pageNumber;
			var $divPage = $("#" + pageId);
			if (!$divPage) {
				return;
			}
			self.hideAllPages();
			self.setCurrentPage(pageNumber);
			$divPage.show();
		},

		/**
		* Moves backward in the wizard by 1 page
		*/
		showPreviousPage: function() {
			// don't move past the beginning
			if (_currentPage == 1) {
				return;
			}
			this.showPage(_currentPage - 1);
		},

		/**
		* Moves forward in the wizard by 1 page
		*/
		showNextPage: function() {
			// don't move past the end
			if (_currentPage == _totalPages) {
				return;
			}
			this.showPage(_currentPage + 1);
		},

		/**
		* Process the current wizard page and moves to the next
		*/
		finishCurrentPage: function() {
			switch (_currentPage) {
				case 1:
					self.finishPageOne();
					break;
				case 2:
					self.finishPageTwo();
					break;
				case 3:
					self.finishPageThree();
					break;
			}
		},

		/**
		* Clears all previously selected options from the wizard
		*/
		clearAll: function() {
			_benchmarkToolConfig = new atlas.BenchmarkToolConfig();
			getIndicatorSelector(indicatorSelectorNamespace).clearSelectedIndicators();
			_locationSelector1.clearSelections();
			_locationSelector2.clearSelections();
		}

	}

	//// Constructor ////

	//configure DatacenterContainer to load entities asynchronously from the web service
	velir.datacenter.DatacenterContainer.entitySearchService = "/services/EntitySearch.asmx";

	// load configuration from the query string and fill-out the previously selected options in the wizard
	self.loadConfiguration();
	
	return pub;
}

