/*

POST related domain search request to doteasy API thru ajax
SHOW "loading" hourglasses in place of the domain selection checkboxes
GET response from ajax and SHOW available related domain names in place of the hourglasses

author: [AC]
date:   mar 22, 2008

// REQUIRE
   /_js/dom/abbr.js
   /_js/ajax/ajax.js


// [START] FUNCTION LIST

	// strName = name to search
	// strDomainNameListId = DOM ID of <ul> list hosting the result domain list
	// strResultHiddenInputId = DOM ID of <input:hidden> field which store the result for form-posting
this.init(strName, strDomainNameListId, strResultHiddenInputId) {}

	// post search name thru AJAX to doteasy's API
	// ajax will then pass result to the ajax.callback function
	// strExtGroup is defined by doteasy.  To date: [''|'.com'|'.uk'|'cctld']
this.submitSearch(numDomains) {}

	// deliver result: from result string to GUI display
this.deliverResult(str) {}

	// re-try searching and delivering the result
this.retrySearch() {}

	// get array of <li class="domainname-con"> elements
this.getAllDomainNameBoxes() { return arrDomainNameBoxes; }

	// get one <li class="domain-%numIndex"> elem, numIndex is number starting at zero
this.getOneDomainNameBox(numIndex) { return elemBox; }

	// get <div class="error-message"> elem inside the domain result list
this.getErrorMessageBox() { return elemBox; }

	// write strValue to all domain name <li class="domain-%numIndex"> box, AND hide/show <div class="input">
this.writeAllDomainNameBox(strValue, boolShowInput) {}

	// write strValue to one ext box <li class="%strExt"><div class="domainname">, AND hide/show <div class="input">, strExt has NO leading dot
this.writeOneDomainNameBox(numIndex, domainName) {}

	// hide domain name box of given index, used when there are not enough availabe domain names to fill up all the boxes
this.hideOneDomainNameBox(numIndex) {}

	// write error message and "retry" link
this.writeErrorMessage(errorMessage) {}

	// function to format var-safe-name: trim leading dot from the given string and convert inner dot to underscore, if any.  for use of preping ext name
this.formatVarSafeName(str) { return strResult; }

// [END] FUNCTION LIST


// [START] EXAMPLE

<cfoutput>

<cfset nameToSearch = "yahoo">
<script type="text/javascript" src="/_js/dom/abbr.js"></script>
<script type="text/javascript" src="/_js/ajax/ajax.js"></script>
<script type="text/javascript" src="/_js/domain-search/related-domain-search-ajax.js"></script>

<ul id="list-#nameToSearch#" class="list-result">
<li class="domainname-con domain-0"><div class="input"><input type="checkbox" name="" value=""></div><div class="domainname"></div></li>
<li class="domainname-con domain-1"><div class="input"><input type="checkbox" name="" value=""></div><div class="domainname"></div></li>
<li class="domainname-con domain-2"><div class="input"><input type="checkbox" name="" value=""></div><div class="domainname"></div></li>
<div class="error-message"></div>
</ul>
<input type="hidden" id="js:var:strResultHiddenInputId" value=""><!--- name 'strResultHiddenInputId' is given to this.init(), value to be set by this.deliverResult() --->
<input type="hidden" id="js:var:strErrorHiddenInputId" value=""><!--- name 'strErrorHiddenInputId' is given to this.init(), value to be set by this.deliverResult() IF there is an error --->

<script type="text/javascript">
var rds = new RelatedDomainSearch('rds');
rds.init('#nameToSearch#', 'list-#nameToSearch_VarSafe#', 'available-related-domain-names-list-#nameToSearch_VarSafe#');
rds.submitSearch(3);
</script>


</cfoutput>

// [END] EXAMPLE

*/

function RelatedDomainSearch(objName) {

	var me = this;
	this.NUMBER_OF_DOMAINS = 20;
	// var RELATED_DOMAIN_SEARCH_API_URL = '/_lab/domainsearch/index.cfm';
	// var RELATED_DOMAIN_SEARCH_API_URL = '/_api/domain-search/search-related-names.cfm?numberOfDomains='+NUMBER_OF_DOMAINS;
	var RELATED_DOMAIN_SEARCH_API_URL = '/_api/domain-search/search-related-names.cfm';
	

	this.strName = '';
	this.strDomainNameListId = '';
	this.strResultHiddenInputId = ''; // name of <input type="hidden" ... /> which will store the comma-list of available extensions after search is done.  see this.deliverResult()
	this.strErrorHiddenInputId = ''; // name of <input type="hidden" ... /> which will store the error message if there is a search error.  see this.deliverResult()
	this.defaultDomainNameHtml = '<img src="/Images/loading.gif" />';
	this.onDeliverResult = null; // function to run at the end of running this.deliverResult.  Set this before calling this.init().

	this.init = function(strName, strDomainNameListId, strResultHiddenInputId, strErrorHiddenInputId) {
		this.strName = strName;
		this.strDomainNameListId = strDomainNameListId;
		this.strResultHiddenInputId = strResultHiddenInputId;
		this.strErrorHiddenInputId = strErrorHiddenInputId;
	}
	
	this.submitSearch = function() {
		this.writeAllDomainNameBox(this.defaultDomainNameHtml, false);
		var ajax = new AJAX();
		ajax.url = RELATED_DOMAIN_SEARCH_API_URL;
		ajax.method = 'POST';
		ajax.params = 'DomainNameNoExt=' + this.strName + '&numberOfDomains=' + this.NUMBER_OF_DOMAINS.toString();
		ajax.callback = objName + '.deliverResult';
		ajax.send();
	}

	this.deliverResult = function(str) {
		var blnValidResult = true;
		var	arrResult = new Array();
		var strErrorMessage = '';
		// [TODO] parse result for validity
		if (str.substring(0,7).toLowerCase() == 'error::') {
			blnValidResult = false;
			strErrorMessage = str.substring(7);
		}
		if (blnValidResult) {
			// parse result str.  e.g., 'mydomain01.com,youdomain02.net'
			arrResult = str.split(',');
		}
		var arrAvailableExt = new Array();
		// for each result domain name
		for (var ii=0; ii<arrResult.length; ii++) {
			var strDomainName = arrResult[ii];
			// write GUI!
			this.writeOneDomainNameBox(ii, strDomainName);
			// save result to array
			arrAvailableExt.push(strDomainName);
		}
		// write available ext list to hidden input
		if (this.strResultHiddenInputId) {
			var elemResultHiddenInput = ge(this.strResultHiddenInputId);
			elemResultHiddenInput.value = arrAvailableExt.join(',');
		}
		// IF there are less available domain names than prepared boxes
		if (arrResult.length < this.NUMBER_OF_DOMAINS) {
			// hide unused boxes
			for (var ii=arrResult.length; ii<this.NUMBER_OF_DOMAINS; ii++) {
				this.hideOneDomainNameBox(ii);
			}
		}
		// write error message for invalid result
		if (!blnValidResult) {
			this.writeErrorMessage(strErrorMessage);
			// write error message to hidden input
			if (this.strErrorHiddenInputId) {
				var elemErrorHiddenInput = ge(this.strErrorHiddenInputId);
				elemErrorHiddenInput.value = strErrorMessage;
			}
		}
		// call event handler
		if (this.onDeliverResult) {
			this.onDeliverResult();
		}
	}

	this.retrySearch = function() {
		// hide error message box
		var elemErrorMessageBox = this.getErrorMessageBox();
		elemErrorMessageBox.style.display = 'none';

		// clear result hidden input
		if (this.strResultHiddenInputId) {
			var elemResultHiddenInput = ge(this.strResultHiddenInputId);
			elemResultHiddenInput.value = '';
		}

		// clear error hidden input
		if (this.strErrorHiddenInputId) {
			var elemErrorHiddenInput = ge(this.strErrorHiddenInputId);
			elemErrorHiddenInput.value = '';
		}

		// write default html for each search result box
		this.writeAllDomainNameBox(this.defaultDomainNameHtml, false);	
		
		// submit search
		this.submitSearch();
	}

	this.getAllDomainNameBoxes = function() {
		var elemList = ge(this.strDomainNameListId);
		var arrDomainNameBoxes = gtc(elemList, 'li', 'domainname-con');
		return arrDomainNameBoxes;
	}

	this.getOneDomainNameBox = function(numIndex) {
		var elemList = ge(this.strDomainNameListId);
		var arrDomainName = gtc(elemList, 'li', 'domain-'+numIndex);
		var elemBox = arrDomainName[0];
		return elemBox;
	}

	this.getErrorMessageBox = function() {
		var elemList = ge(this.strDomainNameListId);
		var arrErrorMessageBox = gtc(elemList, 'li', 'error-message');
		var elemBox = arrErrorMessageBox[0];
		return elemBox;
	}


	this.writeAllDomainNameBox = function(strValue, boolShowInput) {
		var arrDomainName = this.getAllDomainNameBoxes();
		for (var ii=0; ii<arrDomainName.length; ii++) {
			var elemBox = arrDomainName[ii];
			var elemInputDiv = gtc(elemBox, 'div', 'input')[0];
			var elemDomainNameDiv = gtc(elemBox, 'div', 'domainname')[0];
			elemInputDiv.style.display = (boolShowInput)?'inline':'none'; // NOTE: display is 'inline', not 'block'
			elemDomainNameDiv.innerHTML = strValue;
			elemBox.style.display = 'block';
		}
	}

	this.writeOneDomainNameBox = function(numIndex, domainName) {
		var elemBox = this.getOneDomainNameBox(numIndex);
		var strValue = domainName;
		var boolShowInput = true;
		if (elemBox) {
			// get div containers
			var elemInputDiv = gtc(elemBox, 'div', 'input')[0];
			var elemDomainNameDiv = gtc(elemBox, 'div', 'domainname')[0];
			// show/hide checkbox
			elemInputDiv.style.display = (boolShowInput)?'inline':'none'; // NOTE: display is 'inline', not 'block'
			// write domain name
			elemDomainNameDiv.innerHTML = strValue;
			// get checkbox <input> dom elem
			var elemCheckbox = gtc(elemInputDiv, 'input', 'checkbox')[0];
			// set input checkbox name & value
			// elemCheckbox.name = 'selectedRelatedDomainNameList_' + me.formatVarSafeName(domainName);
			elemCheckbox.value = domainName;
		}
	}

	this.hideOneDomainNameBox = function(numIndex) {
		var elemBox = this.getOneDomainNameBox(numIndex);
		elemBox.style.display = 'none';
	}

	this.writeErrorMessage = function(errorMessage) {
		var elemBox = this.getErrorMessageBox();
		var retryLinkHtml = ' <a href="#" onClick="' + objName + '.retrySearch(); return false;">Search Again</a>';
		elemBox.innerHTML = errorMessage + retryLinkHtml;
		elemBox.style.display = 'block';
	}

	this.formatVarSafeName = function(str) {
		var strResult = '';
		if (str.substring(0,1) == '.') {
			strResult = str.substring(1);
		}
		strResult = strResult.replace(/\./, '_');
		return strResult;
	}

}
