// copyright 2006, Peter Tyrrell, Andornot Consulting

/* HELPERS */

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };
String.prototype.trimSeparator = function(separator) 
{
	var output = this;
	if (output.indexOf(separator + separator) != -1)
	{
		output = output.replace(separator + separator, separator);	
	}
	if (output.indexOf(separator) == 0)
	{
		output = output.substring(separator.length, output.length);
	}
	else if (output.lastIndexOf(separator) == (output.length - separator.length))
	{
		output = output.substring(0, (output.length - separator.length));
	} 
	return output;
}

// event listener
function addEvent(o,e,f)
{
	if (o.addEventListener){ o.addEventListener(e,f,true); return true; }
	else if (o.attachEvent){ return o.attachEvent("on"+e,f); }
	else { return false; }
}

/*
GetQueryParamByKey() returns the query parameter value if any match found for key.
*/
function GetQueryParamByKey(key, strQuery) // returns string
{
	var output = "";
	if (!strQuery)
	{
		strQuery = window.location.search.substring(1);
	}
	var arrPairs = strQuery.split("&");
	var i = 0, pos = 0;
	
	for (i=0;i<arrPairs.length;i++)
	{
		pos = arrPairs[i].indexOf('=');
		if (pos >= 0)
		{
			if (key.toLowerCase() == arrPairs[i].substring(0,pos).toLowerCase())
			{
				output = arrPairs[i].substring(pos+1);
				break;
			}
		}
	}
	return output;
}


/********************************
NEXTPREVIOUS
Functions to page back and forth in WebPublisher search results
********************************/

/*
NEXTPREVIOUS GLOBAL VARIABLES
*/

// global page url
var currentUrl = window.location.href;

if (currentUrl.indexOf("?") != -1)
{
	currentUrl = currentUrl.substr(0, currentUrl.indexOf("?")); //snip href minus query string
}

// global link text values
var npFirstText = "First";
var npPreviousText = "Previous {MR}";
var npNextText = "Next {MR}";
var npLastText = "Last";

var npFirstRecordText = "First";
var npPreviousRecordText = "Previous";
var npNextRecordText = "Next";
var npLastRecordText = "Last";

//global page range values
var npPageRange = 10;
var npPageRangePreText = "";
var npPageRangePostText = "";

//global show MR count in link text
var npShowMR = true;

//global css class names
var npLinkCss = "nextprev_link";
var npTextCss = "nextprev_text";


/*
Next/previous BLOCK section 
Use in reports where multiple records shown at a time
*/

function nextprev_First()
{
	var params = window.dbtw_params;
	var text = npFirstText;
	var output = "";
	var first_params = "";
	
	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);
	
	// prepare link text
	if (npShowMR == true)
	{
		text = text.replace(/{MR}/g, mr.toString());
	}
	else 
	{
		text = text.replace(/{MR}/g, "");
	}
	text = text.trim();
	
	// determine whether a link should be made
	if (rn == 0)
	{
		output += "<span class='" + npTextCss + "'>" + text + "</span>";
	}
	else
	{
		var first_params = params.replace((/RN=(\d+)/), "RN=" + mr.toString());
		output += "<a href='" + currentUrl;
		output +=  "?AC=PREV_BLOCK" + first_params;
		output += "' class='" + npLinkCss + "'>"; 
		output += text;
		output += "</a>";
	}
	return output;

}

function nextprev_Previous()
{
	var params = window.dbtw_params;
	var text = npPreviousText;
	var output = "";		

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);
	
	//comparison number for prev block
	var prev_total = (rn - mr);
	
	// prepare link text
	if (npShowMR == true)
	{
		text = text.replace(/{MR}/g, mr.toString());
	}
	else 
	{
		text = text.replace(/{MR}/g, "");
	}
	text = text.trim();
	
	// determine if a link should be made
	if (prev_total >= 0 && mr != 0)
	{
		output += "<a href='" +  currentUrl;
		output +=  "?AC=PREV_BLOCK" + params;
		output += "' class='" + npLinkCss + "'>";
		output += text;
		output += "</a>";
	}
	else if (mr == 0)
	{
		output += "<span class='" + npTextCss + "'>" + text + "</span>";
	}
	else
	{
		output += "<span class='" + npTextCss + "'>" + text + "</span>";
	}

	return output;

}

function nextprev_Next(record_count)
{
	var params = window.dbtw_params;
	var text = npNextText;
	var output = "";
	var rc = parseInt(record_count);		

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);
	
	// prepare link text
	if (npShowMR == true)
	{
		text = text.replace(/{MR}/g, mr.toString());
	}
	else 
	{
		text = text.replace(/{MR}/g, "");
	}
	text = text.trim();
	
	//comparison number for next block
	var next_total = (rc - mr - rn);

	// determine if a link should be made
	if (next_total > 0 && mr != 0)
	{
		output += "<a href='" + currentUrl;
		output +=  "?AC=NEXT_BLOCK" + params;
		output += "' class='" + npLinkCss + "'>";
		output += text;
		output += "</a>";	
	}
	else if (mr == 0)
	{
		output += "<span class='" + npTextCss + "'>"+text;
		output += "</span>";	
	}	
	else
	{
		output += "<span class='" + npTextCss + "'>"+text;
		output += "</span>";	
	}
	
	return output;

}

function nextprev_Last(record_count)
{
	var params = window.dbtw_params;
	var text = npLastText;
	var output = "";
	var last_params = "";
	var rc = parseInt(record_count);

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);
	
	// prepare link text
	if (npShowMR == true)
	{
		text = text.replace(/{MR}/g, mr.toString());
	}
	else 
	{
		text = text.replace(/{MR}/g, "");
	}
	text = text.trim();
	
	//comparison number for next block
	var last_total = (rc - mr - rn);
		
	// determine if a link should be made
	if (last_total <= 0)
	{
		output = "<span class='" + npTextCss + "'>"+text;
		output += "</span>";
	}
	else
	{
		var last_RN = (Math.floor(((rc-1) / mr)) - 1) * mr;
		var last_params = params.replace((/RN=(\d+)/), "RN=" + last_RN);
		
		output += "<a href='" + currentUrl;
		output +=  "?AC=NEXT_BLOCK" + last_params;
		output += "' class='" + npLinkCss + "'>";
		output += text;
		output +="</a>";
	}
	
	return output;
}

/*
nextprev_PageRange() provides an sliding numeric alternative to next/previous links
*/

function nextprev_PageRange(record_count)
{
	var params = window.dbtw_params;
	var rc = parseInt(record_count);
	var i = 0;
	var j = 0;
	var pre_params = "";
	var post_params = "";
	var pre_link = "";
	var post_link = "";	
	var current_write = "";
		
	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);	
	
	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);	
	
	// determine current page	
	var current_page = (rn / mr) + 1
	
	if ( rc % mr == 0)
	{
		var total_page = rc / mr
	}
	else 
	{
		var total_page = ((rc - (rc%mr)) / mr) + 1
	}	

	// build links before current page
	if ((total_page - current_page) < (Math.round(npPageRange / 2) - 1))
	{
		var PreSlider = (npPageRange - (total_page - current_page)) - 1;
	}
	else
	{
		var PreSlider = Math.round(npPageRange / 2);
	}
	var PreCount = 0;
	for (i = current_page - PreSlider; i < current_page; i++)
	{		
		if (i <= 0)
		{
			continue;	
		}
		else
		{
			pre_params = params.replace((/RN=(\d+)/), "RN=" + (mr * i));
			pre_link += "<a href='" + currentUrl;
			pre_link +=  "?AC=PREV_BLOCK" + pre_params;
			pre_link += "' class='" + npLinkCss + "'>"; 
			pre_link += npPageRangePreText + i + npPageRangePostText;
			pre_link += "</a> ";
			
			PreCount++;
		}
	}	
	
	// build links after current page
	var PostSlider = npPageRange - PreCount;
	for (j = current_page + 1; j < (current_page + PostSlider); j++)
	{		
		if (j > total_page)
		{
			break;	
		}
		else
		{
			post_params = params.replace((/RN=(\d+)/), "RN=" + (mr * (j-2)));
			
			post_link += "<a href='" + currentUrl;
			post_link +=  "?AC=NEXT_BLOCK" + post_params;
			post_link += "' class='" + npLinkCss + "'>";
			post_link += npPageRangePreText + j + npPageRangePostText;
			post_link +="</a> ";	
					
		}
	}
	
	current_write = "<span class='" + npTextCss + "'>" + npPageRangePreText + current_page + npPageRangePostText + "</span> "
	
	return pre_link + current_write + post_link;	
}


/*
Next/previous RECORD section
Use in full display where one record shown at a time
*/

function nextprevRecord_First()
{
	var params = window.dbtw_params;
	var text = npFirstRecordText;
	var output = "";

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);
		
	// determine if a link should be made
	if (rn > 0)
	{
		var first_params = params.replace((/RN=(\d+)/), "RN=1");
		output += "<a href='" + currentUrl;
		output +=  "?AC=PREV_RECORD" + first_params;
		output += "' class='" + npLinkCss + "'>";
		output += text + "</a>";
	}
	else
	{
		output = "<span class='" + npTextCss + "'>"+text+"</span>";	
	}

	return output;

}

function nextprevRecord_Previous()
{
	var params = window.dbtw_params;
	var text = npPreviousRecordText;
	var output = "";

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// determine if a link should be made
	if (rn > 0)
	{
		output += "<a href='" +  currentUrl;
		output +=  "?AC=PREV_RECORD" + params;
		output += "' class='" + npLinkCss + "'>";
		output += text + "</a>";
	}
	else
	{
		output = "<span class='" + npTextCss + "'>"+text+"</span>";	
	}

	return output;

}

function nextprevRecord_Next(record_count)
{
	var params = window.dbtw_params;
	var text = npNextRecordText;
	var output = "";
	var rc = parseInt(record_count);

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);
	
	// determine if a link should be made
	if (rn+1 < rc)
	{
		output += "<a href='" + currentUrl;
		output +=  "?AC=NEXT_RECORD" + params;
		output += "' class='" + npLinkCss + "'>";
		output += text + "</a>";
	}
	else
	{
		output = "<span class='" + npTextCss + "'>"+text+"</span>";	
	}

	return output;

}

function nextprevRecord_Last(record_count)
{
	var params = window.dbtw_params;
	var text = npLastText;
	var output = "";
	var rc = parseInt(record_count);

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);
	
	// determine if a link should be made
	if (rn+1 < rc)
	{
		var last_params = params.replace((/RN=(\d+)/), "RN=" + (rc-2));
		output += "<a href='" + currentUrl;
		output +=  "?AC=NEXT_RECORD" + last_params;
		output += "' class='" + npLinkCss + "'>";
		output += text + "</a>";
	}
	else
	{
		output = "<span class='" + npTextCss + "'>"+text+"</span>";	
	}

	return output;

}

/*
 This back_to_block method written by Terry McBride tttmcbride@yahoo.com
 This method takes you from a display of an expanded record back to  the list from the position that the current expanded record would be in.
*/

function back_to_block() 
{
	var params = window.dbtw_params;

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);

	// find the lower multiple of mr and add another mr to it to fool PREV_BLOCK
	var remainder = (rn % mr);
	var start = (rn - remainder + mr); 

	var i = params.indexOf("RN=") + 3;
	var j = params.indexOf("&", i);

	var url = currentUrl + "?AC=PREV_BLOCK" + params.substring (0, i) + start + params.substring(j, params.length);

	window.location.href = url; 

}

/*
back_to_block_cookie() sets a cookie with the back_to_block query string
*/

function back_to_block_cookie(Textbase) 
{
	var params = window.dbtw_params;

	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);

	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);

	// find the lower multiple of mr and add another mr to it to fool PREV_BLOCK
	var remainder = (rn % mr);
	var start = (rn - remainder + mr); 

	var i = params.indexOf("RN=") + 3;
	var j = params.indexOf("&", i);

	var url = currentUrl + "?AC=PREV_BLOCK" + params.substring (0, i) + start + params.substring(j, params.length);
	
	document.cookie = Textbase + "_DbtwLastResult=" + url + "; path=/";
	
}

function back_to_record_cookie(Textbase, RecordNumber)
{
	var params = window.dbtw_params;
	var rn = parseInt(RecordNumber) - 1;
	var i = params.indexOf("RN=") + 3;
	var j = params.indexOf("&", i);
	
	// reconstruct the link with only the RN value replaced
	var url = currentUrl + "?AC=GET_RECORD" + params.substring (0, i) + rn + params.substring(j, params.length);
	document.cookie = Textbase+ "_DbtwFullRecord=" + url + "; path=/";
}

function record_count_cookie(Textbase, RecordCount)
{
	document.cookie = Textbase + "_RecordCount=" + RecordCount + "; path=/";
}

/*
ExpandRecord() emulates the WebPublisher expand link
*/

function ExpandRecord(recordnum)
{
	var params = dbtw_params;
	var snipA = "";
	var snipZ = "";
	var myUrl = window.location.href.replace(window.location.search, "");
	
	if (recordnum == 1)
	{
		snipA = params.indexOf("RN=") + 3;
		snipZ = params.indexOf("&", snipA);
		params = params.substring(0, snipA) + (recordnum) + params.substring(snipZ, params.length);
		myUrl += "?AC=PREV_RECORD" + params;
	}
	else
	{
		snipA = params.indexOf("RN=") + 3;
		snipZ = params.indexOf("&", snipA);
		params = params.substring(0, snipA) + (recordnum-2) + params.substring(snipZ, params.length);	
		myUrl += "?AC=NEXT_RECORD" + params;
	}
	
	window.location.href = myUrl;
}

/*
LastRecordNumber() gets last record number on page
*/
function LastRecordNumber(count)
{
	var params = dbtw_params;
	var output = "";
	
	// find the record number
	var rns = params.match(/RN=(\d+)/);
	var rn = parseInt(rns[1]);	
	
	// MR is records at a time
	var mrs = params.match(/MR=(\d+)/);
	var mr = parseInt(mrs[1]);	
	
	//debug
//	if ((typeof console) != "undefined")
//	{
//	    console.log("rn="+rn+", mr="+mr+", count="+count);
//	}
	
	// count < mr = one page of results only
	if (count < mr)
	{
        output = (rn + count).toString();
	}
	else
	{
//	    // last page contains just one result item
//	    if (rn == (count - 1))
//	    {
//	        output = count.toString();
//	    }
	    // (rn + mr) >= count means last page
	    if ((rn + mr) >= count)
	    {
	        output = count.toString();
	    }
	    else
	    {
	        output = (rn + mr).toString();
	    }
	}
	
	return output;
		
}

/*********************************
CHANGEFORM
Functions to switch forms while in WebPublisher
*********************************/

/*
Used in webforms to select other forms from a dropdown.
Option values contain actual form names, so option text is flexible.
*/
function dbtw_form_change_onvalue(select_object, action, params)
   {
   	//alert("enter");
   var new_form = escape( select_object.options[select_object.selectedIndex].value );
   var i = new_form.indexOf( "+" );
   while ( i >= 0 )
   {
	   new_form = new_form.substring( 0, i ) +
	               "%2B" +
	               new_form.substring( i+1, new_form.length );
	   i = new_form.indexOf( "+" );
	}

   var form_key = "RF=";
   var n1 = params.indexOf( form_key );
   var n2 = n1 + form_key.length;
   var n3 = params.indexOf( "&", n2 );
   var n4 = params.length;
   var form_change_url = action + "?AC=CHANGE_REPORT" +
                           params.substring( 0, n2 ) +
                           new_form +
                           params.substring( n3, n4 );
	window.location.href = form_change_url;
   }
   
   
/*
Used in web reports to change forms generically without a select object.
*/   
function dbtw_report_change(report_name, action, params)
{
   var new_form = escape(report_name);
   var i = new_form.indexOf( "+" );
   while ( i >= 0 )
   {
	   new_form = new_form.substring( 0, i ) +
	               "%2B" +
	               new_form.substring( i+1, new_form.length );
	   i = new_form.indexOf( "+" );
	}

   var form_key = "RF=";
   var n1 = params.indexOf( form_key );
   var n2 = n1 + form_key.length;
   var n3 = params.indexOf( "&", n2 );
   var n4 = params.length;
   var form_change_url = action + "?AC=CHANGE_REPORT" +
                           params.substring( 0, n2 ) +
                           new_form +
                           params.substring( n3, n4 );
	window.location.href = form_change_url;
}

/*
Used in web full displays to change forms generically without a select object.
*/ 
function dbtw_display_change(display_name, action, params)
{
   var new_form = escape(display_name);
   var i = new_form.indexOf( "+" );
   while ( i >= 0 )
   {
	   new_form = new_form.substring( 0, i ) +
	               "%2B" +
	               new_form.substring( i+1, new_form.length );
	   i = new_form.indexOf( "+" );
	}

   var form_key = "DF=";
   var n1 = params.indexOf( form_key );
   var n2 = n1 + form_key.length;
   var n3 = params.indexOf( "&", n2 );
   var n4 = params.length;
   var form_change_url = action + "?AC=CHANGE_DISPLAY" +
                           params.substring( 0, n2 ) +
                           new_form +
                           params.substring( n3, n4 );
	window.location.href = form_change_url;
}




/***********************
URLTAMER
***********************/

/*
Shortens a single or multiple URL strings to maximum number of characters.
*/

function URLTamer(url, maxlen)
{
  var mid;
  var takeaway;
  var strfirsthalf;
  var strbefore;
  var strafter;
  var strfinal = "";
  var ellipsis = "...";
  var splitchar = "|split|";
  var arrurl = new Array();
  var i;
  

  // split url string if splitchar is found
  arrurl = url.split(splitchar);
  
  // loop through the array, building hyperlink for each member
  for (i=0; i<arrurl.length; i++)
  {
  	if (arrurl[i].length > maxlen)
	{	
		mid = Math.round(arrurl[i].length / 2);
		takeaway = Math.round((arrurl[i].length - maxlen) / 2);
		takeaway += ellipsis.length / 2;
		takeaway = Math.round(takeaway);
				
		strbefore = arrurl[i].substring(0, mid);
		strbefore = strbefore.substring(0, strbefore.length + 1 - takeaway);
						
		strafter = arrurl[i].substring(mid, arrurl[i].length + 1);
		strafter = strafter.substring(takeaway, strafter.length + 1);
				
		strfinal += "<a target=\"_blank\" href=\"" + arrurl[i] + "\">"
				+ strbefore + ellipsis + strafter
				+ "</a><br />";
	}
	else
	{
		strfinal += "<a target=\"_blank\" href=\"" + arrurl[i] + "\">"
				+ arrurl[i]
				+ "</a><br />";
	}
  }
  
  return strfinal;
}


/*******************************************************************************
REWIND
Functions to return to search page without hard-coding urls into results pages,
for both 'new search' and 'revise search'
*******************************************************************************/

/*
Rewind() relocates to the original search page when in WebPublisher results.
*/
function Rewind(mode)
{
	if (mode == "fullrecord")
	{
		back_to_block();		
	}
	else if (mode == "remember")
	{
		var rewindUrl = GetQueryParamByKey("BU", dbtw_params);
		rewindUrl = decodeURIComponent(rewindUrl);
		//console.log(rewindUrl);
		if (rewindUrl)
		{		
			if (rewindUrl.indexOf("?") != -1)	
			{
				rewindUrl = rewindUrl.substr(0, rewindUrl.indexOf("?")); //snip query string from end	
			}
			window.location.href = rewindUrl + "?remember=true";
		}
		else
		{
			alert("Cannot rewind: search page URL cannot be found");
		}
	}
	else if (mode == null)
	{
		var rewindUrl = GetQueryParamByKey("BU", dbtw_params);
		rewindUrl = decodeURIComponent(rewindUrl);
		if (rewindUrl)
		{		
			if (rewindUrl.indexOf("?") != -1)	
			{
				rewindUrl = rewindUrl.substr(0, rewindUrl.indexOf("?")); //snip query string from end	
			}
			window.location.href = rewindUrl;
		}
		else
		{
			alert("Cannot rewind: search page URL cannot be found");
		}
	}
}


/********************
SEE ALSO
Functions to create see-also links from WebPublisher content
********************/

/*
SeeAlso() creates see-also links from field content; avoids triple trick and '--' problem in html comments.
Multiple entries okay.
Separator text must be: |split|.
Does not allow carriage returns.
*/

function SeeAlso(FieldContent, FieldName, Separator)
{
	var SplitChar = "|split|";
	var FieldValues = [];
	var i = 0;
	var Str = '';
	var Path = window.location.pathname;
	
	FieldValues = FieldContent.split(SplitChar);
	for (i=0;i<FieldValues.length;i++)
	{
		if (Str.length > 0)
		{
			Str += Separator;	
		}
		Str += '<a href=\"';
		Str += Path;
		Str += CreateSeeAlsoQuery(FieldValues[i], FieldName);
		Str += '\">';
		Str += FieldValues[i];
		Str += '</a>';
	}
	document.write(Str);
}

function CreateSeeAlsoQuery(value, field)
{
	var SeeAlsoParams = dbtw_params;
	var Query =  "?AC=SEE_ALSO&QF0=" + field + "&QI0==" + encodeURIComponent("\"" + value + "\"") + SeeAlsoParams;
	return Query;
}
