/**
 * @class Static Class that acts as the traffic cop for MasterQuery Objects. Determines
 * where it goes and if there needs to be a debug window displayed.
 *
 * @author Christopher Baker <Christopher.Baker@lexisnexis.com>
 * @version 0.1 
 */

//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
// CONSTANTS

var NEW_WINDOW_FEATURES = 'status=yes,resizable=yes,menubar=yes,scrollbars=yes,toolbar=yes,directories=yes,location=yes'

var searchImplementorCount = 0

/**
 * @constructor
 * @private
 */
function SearchImplementor()
{
	throw new Error("SearchImplementor is a static class. Do not instantiate.");
}

/**
 * Set to true to force a debug popup even in prod.
 */
SearchImplementor.debugOn = false;

/**
 * That action method. Should we do a popup, or assign the Object to an
 * implementor?
 */
SearchImplementor.go = function(mq, forceNoDebug)
{
	if (MasterQuery.NO_DEBUG) {
		forceNoDebug = true;
	}
	if (forceNoDebug)
	{
		SearchImplementor.assign(mq);
		return;
	}

	if (isDev() || SearchImplementor.debugOn)
	{
		SearchImplementor.popup(mq);
	}
	else
	{
		SearchImplementor.assign(mq);
	}
}

/**
 * Open up the debug popup window.
 */
SearchImplementor.popup = function(mq)
{
	newWindow = window.open("","_blank","status=no,left=0,top=0,height=420,width=540,scrollbars=yes");
	SearchImplementor.mqRef = mq;

    newWindow.document.write(SearchImplementor.getDebugPopupHMTL(mq));
    
    newWindow.document.close( ); // close layout stream
}

/**
 * Used to test if we can see the object
 */
SearchImplementor.BOOP = function()
{
	alert("BOOP!")
}

/**
 * Returns the HTML for the debug popup window.
 */
SearchImplementor.getDebugPopupHMTL = function(mq)
{
	var str = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
	str += '<html>\n';
	str += '<head>\n';
	str += '<title>Development Information: Master Query<\/title>\n';

	// Our stylesheet
	str += '<link href="';
	str += MasterQuery.baseURL
	str += 'debugWindow.css" rel="stylesheet" type="text\/css">\n';

	// our javascript files
	str += '<script type="text/javascript" language="javascript" src="';
	str += MasterQuery.baseURL
	str += 'MQInclude.asp"></script>\n';
	
	str += '<script type="text/javascript" language="javascript" src="';
	str += MasterQuery.baseURL
	str += 'MasterQueryDebug.js"></script>\n';
    str += '<script language=javascript>\n';
    str += 'var decode = false;\n';
    str += 'function toggleDecode(link)\n';
    str += '{//alert(document.body.clientHeight + " " + document.documentElement.clientHeight + " " + document.body.clientWidth + " " + document.documentElement.clientWidth);\n';
    //str += 'window.resize(document.body.clientHeight,document.body.clientWidth);\n'
    str += '    var ques = document.MasterQuerySearchImplementor.link.value.indexOf("?");\n';
    str += '    var url = document.MasterQuerySearchImplementor.link.value.slice(0,ques);\n';
    str += '    var queryString = document.MasterQuerySearchImplementor.link.value.slice(ques + 1);\n';
    str += '\n';
    str += '    if (decode == false)\n';
    str += '    {\n';
    str += '        document.MasterQuerySearchImplementor.link.value = url + "?" + decodeURIComponent(queryString).replace(/%3D/g, "=").replace(/%26/g, "&");\n';
    str += '        link.innerHTML = "<font color=black size=\'1\'>Reencode</font>";\n';
    str += '        decode = true;\n';
    str += '    } else\n';
    str += '    {\n';
    str += '        document.MasterQuerySearchImplementor.link.value = url + "?" + encodeURIComponent(queryString).replace(/%3D/g, "=").replace(/%26/g, "&");\n';
    str += '        link.innerHTML = "<font color=black size=\'1\'>Decode</font>";\n';
    str += '        decode = false;\n';
    str += '    }\n';
    str += '    return false;\n';
    str += '}\n';
    str += '</script>\n';
	str += '</head>\n';
	str += '<body onload="init();">';
	str += '<form action="/clients/controls/MasterQuery/test/testSearchImplementor.htm" onsubmit="callBack();" name="MasterQuerySearchImplementor" ID="Form1">';

	str += '<input type="hidden" name="__mqJsonStore__" value=\'' + escape(JSON.stringify(mq))  + '\'>\n'

	str += '<fieldset>\n';
	str += '<legend>\n';
	str += '					Development Information: MasterQuery<\/legend>\n';
	str += '<div class="sublegend">This development-only popup will not be displayed in production.';
	if (SearchImplementor.mqRef.uid != undefined)
    	str += '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="#" onclick="alert(\'Authentication Values:\\n\\nUser ID:    ' + SearchImplementor.mqRef.uid + '\\nPassword: ' + SearchImplementor.mqRef.pwd + '\');return false;"><font color=black>Show ID/PWD</font></a>';
	str += '<\/div>\n<br>\n';
	
	str += '<input type="submit" value="SUBMIT" id="smit" style="margin-left: 120px;" class="b">\n';
	str += '<input type="button" value="CANCEL" class="b" onclick="cancelPopup()">\n';
	str += '<input type="button" value="NO DEBUG" class="b" onclick="cancelPopup();window.opener.MasterQuery.NO_DEBUG = true">\n';
	str += '<br>\n';
	
	str += '<label for="search">QUERY:<\/label> \n';
	str += '<textarea id="search" name="search" rows="3" cols="40">\n';
	str += SearchImplementor.mqRef.getSearch()
	str += '<\/textarea>\n';
	str += '<br>\n';

	str += '<br>\n';
	str += '<div id="additionFields">\n';
	str += SearchImplementor.getAdditionalFields(mq);
	str += '<\/div>';
	str += '<font color=black size=1>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Changes to Link box will not affect search.</font><br />\n';
	str += '<label for="link">LINK:<\/label> \n';
	str += '<input type="text" class="visible" id="link" name="link" value="' + SearchImplementor.getLink(mq) + '">\n';
	str += '<a href="#" onclick="return toggleDecode(this);"><font color=black size="1">Decode</font></a>';
	str += '<br>\n';


	str += '<label for="api">API:<\/label>\n';
	str += '<select name="api" id="api">\n';
	str += SearchImplementor.getAPIOptions(mq.getAPI())
	str += '<\/select>\n';
	str += '<br>\n';

	str += '<hr>\n';
	str += '<div class="debug">debug<\/div>\n';
	str += '<\/fieldset>\n';
	str += '<\/form>\n';
	str += '<\/body>\n';
	str += '<\/html>\n';
	return str;
}

SearchImplementor.getLink = function(mq)
{
	switch(mq.getAPI())
	{
		case 1:
		case 2:
			return CUIBuilderImp.getLink(CUIBuilderImp._preprocessor(mq))
			break;
		case 3:
			return DossierImp.getLink(DossierImp._preprocessor(mq));
			break;
		case 4:
			return GPImp.getLink(GPImp._preprocessor(mq));
			break;
		case 5:
			return LNProfImp.getLink(LNProfImp._preprocessor(mq));
			break;
		case 6:
			return UrlApiImp.getLink(UrlApiImp.preprocessor(mq));
			break;
		case 7:
		case 8:
		case 9:
		case 10:
		case 13:
		case 14:
			return V1SearchImp.getLink(V1SearchImp._preprocessor(mq));
			break;
		case 12:
			return SeisintImp.getLink(SeisintImp._preprocessor(mq));
			break;
		case 18:
			return XLinkPubRecImp.getLinkWithXML(XLinkPubRecImp._preprocessor(mq));
			break;
		case 19:
			return UrlApiPubRecImp.getLink(UrlApiPubRecImp.preprocessor(mq));
			break;

		case 11:
		default:
			return XLinkImp.getLink(XLinkImp._preprocessor(mq));
			break;
	}
	return XLinkImp.getLink(XLinkImp._preprocessor(mq))
}

/**
 * Gets all of the additional custom fields for the MasterQuery Object
 * and determines which ones to display.
 */
SearchImplementor.getAdditionalFields = function(mq)
{
	var fields = SearchImplementor.getMQFieldNames(mq);
	var html = "";

	for (var x = 0; x < fields.length; x++)
	{
		var val;
		if (mq[fields[x]]) { val = mq[fields[x]]; }
		else { val = mq.get(fields[x]); }
        
        if(fields[x] == "domain" && val == undefined)
            val = SearchImplementor.getLink(mq).split("/")[2];
		
		if (val !== null)
		{
			// var fieldName = "MQ" + fields[x];
			// var fieldName = fields[x];
			var fieldName = fields[x];

			var inputType  = "text"
			var inputLabel = '<label for="' +  fieldName + '">' + fields[x].toUpperCase() + ':</label>'
			var linefeed   = "<br clear='all'>";
			var cssClass   =  "visible"

			//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
			// SET DEBUG HIDDEN FIELDS HERE
			switch(fieldName)
			{
				case "method":
				case "target":
				case "override":
				case "protocol":
				case "lexislogo":
				case "lexislogo":
				case "interface":
				case "powernav":
				case "topframe":
				case "docinfo":
				case "mj":
				case "MIDDLEWARE_CODE":
				case "submit":
				case "uid":
				case "pwd":
					inputType = "hidden";
					cssClass  = "hidden";
					inputLabel = "";
					linefeed   = "";
			}

			html += inputLabel;
			html += '<input class="' + cssClass + '" type="' + inputType + '" name="' + fieldName + '" id="' + fieldName + '" value="' + val + '">' + linefeed;
		}
	}
	return html;
}

/**
 * Grabs the name for a specific field. Needed to avoid name collision with
 * core MasterQuery fields.
 */
SearchImplementor.getMQFieldNames = function(mq)
{
	//
	var fields = new Array("searchtype", "source", "after", "fromDate", "toDate", "client", "maxdocs", "menu", "sort","uid","pwd","zone", "originationCode", "target", "TOCTarget", "method", "protocol", "domain",  "override");
	var setArray = new Array()

	// Add existing standard fields
	for (var x = 0; x < fields.length; x++)
	{
		// if (mq[fields[x]] || mq[fields[x]] == "")
		if (mq[fields[x]] || fields[x] == "domain")
		{
			// setArray.push(fields[x])
			setArray[setArray.length] = fields[x];
		}
	}
	// Add custom SET fields
	for (var i in mq)
	{
		if (i.lastIndexOf("c_") == 0) {
			// setArray.push(i.substring(2));
			setArray[setArray.length] = i.substring(2);
		}
	}
	return setArray;
}

/**
 * Returns the API switcher dropdown for the debug popup.
 */
SearchImplementor.getAPIOptions = function(selected)
{
	var ret = ""
	for (var x = 1; x < 20; x++)
	{
		switch(x)
		{
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
				if (x == selected)
				{
					ret += '<option value="' + x + '" selected>' + LNParser.getAPIName(x) + '</option>\n';
				}
				else
				{
					ret += '<option value="' + x + '">' + LNParser.getAPIName(x) + '</option>\n';
				}
			break;
		}

	}
	return ret;
}

/**
 * Returns a DOM Option object
 * DEPRECATED
 */
SearchImplementor.getOption = function(newwin, winame, val)
{
	var dFormOption = newwin.document.createElement("option");
	dFormOption.name  = name
	dFormOption.value = name
	dFormOption.text = val
	return dFormOption
}

/**
 * Sends the MasterQuery Object to a specific implementor.
 */
SearchImplementor.assign = function(mq)
{
	switch(mq.getAPI())
	{
		case 1:
			CUIBuilderImp.submit(mq);
			break;
		case 2:
			CUIBuilderImp.submit(mq);
			// CUIIntBuilderImp(mq);
			break;
		case 3:
			// Add URL API vars
			DossierImp.submit(mq);
			break;
		case 4:
			GPImp.submit(mq);
			break;
		case 5:
			LNProfImp.submit(mq);
			break;
		case 6:
			UrlApiImp.submit(mq);
			break;
		case 7:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_portfolio")
			}
			V1SearchImp.submit(mq);
			break;
		case 8:
			V1SearchImp.submit(mq);
			break;
		case 9:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_searchform")
			}
			V1SearchImp.submit(mq);
			break;
		case 10:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_snews")
			}
			V1SearchImp.submit(mq);
			break;
			
			break;
		case 12:
			// V1SearchImp.submit(mq);
			SeisintImp.submit(mq)
			break;
			
		case 13:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "v1_dossier_launch_forms")
			}
			V1SearchImp.submit(mq);
			break;
		case 14:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "search/searchform")
			}
			V1SearchImp.submit(mq);
			break;
			
		case 15:
			IaLndbImp.submit(mq);
			break;
		case 16:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "removecookie.do")
			}
			IaLndbImp.submit(mq);
			break;
		case 17:
			if (!Truth.isTrue(mq.get("verb")))
			{
				mq.set("verb", "setcookie.do")
			}
			IaLndbImp.submit(mq);
			break;
		case 18:
			XLinkPubRecImp.submit(mq);
			// GetAndPrintImp.submit(mq)
			break;
		case 19:
			UrlApiPubRecImp.submit(mq);
			break;

		case 11:
		default:
			XLinkImp.submit(mq)
	}
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * a query string.
 */
SearchImplementor.getQueryString = function(mq, matrix)
{
	var divider = "";
	var ret = "";

	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}
			if ((matrix[key] != -1) && (matrix[key] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key) && Truth.isTrue(mq[prop]))
				{
					if (typeof matrix[key] == "string") {
						key = matrix[key];
					}
					
					try
					{
						// ret += divider + key + "=" + encodeURIComponent(mq[prop].toString())
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					catch(e)
					{
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					
					divider = "&";
				}
			}

		}
	}
	return ret;
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * a query string.
 */
SearchImplementor.getQueryStringCaseInsensative = function(mq, matrix)
{
	var divider = "";
	var ret = "";

	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}


			if ((matrix[key.toLowerCase()] != -1) && (matrix[key.toLowerCase()] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key.toLowerCase() && Truth.isTrue(mq[prop])))
				{
					if (typeof matrix[key.toLowerCase()] == "string") {
						key = matrix[key.toLowerCase()];
					}
					
					try
					{
						// ret += divider + key + "=" + encodeURIComponent(mq[prop].toString())
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					catch(e)
					{
						ret += divider + key + "=" + escape(mq[prop].toString())
					}
					
					divider = "&";
				}
			}
		}
	}

	return ret;
};

/**
 * Takes a MasteryQuery object and its API matrix and converts it into
 * the HTML for a hidden form post.
 */
SearchImplementor.getPostFields = function(mq, matrix)
{
	var ret = "";
	for (var prop in mq)
	{
		if ((typeof mq[prop] != "object") && typeof mq[prop] != "function")
		{
			var key

			if (prop.substring(0, 2) == "c_")
			{
				key = prop.substring(2)
			}
			else
			{
				key = prop
			}

			if ((matrix[key] != -1) && (matrix[key] != -2))
			{
				if (!SearchImplementor.isNonAPIField(key) && Truth.isTrue(mq[prop]))
				{
					if (typeof matrix[key] == "string") {
						key = matrix[key];
					}

					ret += FormUtil.getHiddenFieldVal(key, mq[prop].toString());
				}
			}
		}
	}
	

	return ret;
};

/**
 * Returns true for field names that are used for MasterQuery and not any specific
 * LN API
 */
SearchImplementor.isNonAPIField = function(field)
{
	switch(field) {
		case "api":
		case "method":
		case "target":
		case "override":
			return true;
		default:
			return false;
	}
};

/**
 * postit takes a MasterQuery Object, its API matrix and form action
 * and dynamically gererate a form out of it that will be posted to the
 * API.
 */
SearchImplementor.postit = function(mq, matrix, action)
{
	searchImplementorCount++

	mq = LNParser.convertDateToQuery(mq)

	var dForm    = document.createElement("form")
	dForm.name   = "mqdynaform" + searchImplementorCount
	dForm.id     = "mqdynaform" + searchImplementorCount
	dForm.action = action

	dForm.method = mq.method
	dForm.method = "GET"

	dForm.target = mq.target

	for (var prop in mq)
	{
		if (typeof mq[prop] != "object")
		{
			var key = prop;
			if (!SearchImplementor.isNonAPIField(key))
			{
				if (typeof matrix[prop] == "string") {
					key = matrix[prop];
				}
				var inp   = document.createElement("input");
				inp.type  = "hidden";
				inp.name  = key;
				inp.value = mq[prop].toString();
				dForm.appendChild(inp);
			}
		}
	}
	document.body.appendChild(dForm);

	dForm.submit();

};

SearchImplementor.submitDiv = function(formHTML)
{
	var diver = document.getElementById("masterQueryDynaFormDiv");

    //If the div already exists then delete it and append a new form
	if(diver != null)
	{
	    document.body.removeChild(document.getElementById("masterQueryDynaFormDiv"));
	}
    
	diver = document.createElement("div");
	diver.id = "masterQueryDynaFormDiv";
	
	diver.innerHTML = formHTML;
	
   	document.body.appendChild(diver);

	var dForm = document.getElementById("masterQueryDynaForm");

	dForm.submit();
}

SearchImplementor.tokenize = function(chunnel)
{
	var xmlObj = null;
	
	if(window.XMLHttpRequest)
    {
        xmlObj = new XMLHttpRequest();        
    }
    else if(window.ActiveXObject)
    {   
        try
        {
            xmlObj = new ActiveXObject("Msxml2.XMLHTTP");            
        }
        catch(e)
        {
            xmlObj = new ActiveXObject("Microsoft.XMLHTTP");            
        }
    }    
    else  
    {
        return false;
    }

	var file = "/clients/controls/Userinf/authTokenHelper.aspx";
	file = file + "?id=" + chunnel.getUID() + "&pwd=" + chunnel.getPWD();
	//alert(file);
	xmlObj.open ('GET', file, false);
	xmlObj.send (null);
      
	var temp;
	temp = xmlObj.responseText;
	
	chunnel.authToken = temp;
	chunnel.setUID("");
	chunnel.setPWD("");
	//alert(temp);

    return chunnel;
}