var DEFAULT_ITEM_ID = -999999;
var MYSPACE_ICON_URL = "Images/MySpace.gif";
var HOMEPAGE_ICON_URL = "Images/home.gif";
var BAND_ICON_ICON_URL = "Images/icon.gif";

function Global_Init()
{
	var oShowFilterCheckBox = document.getElementById( "NavCol_cbxUseShowFilter" );
	if ( oShowFilterCheckBox )
	{
		SetShowFilterDisplay();
	}

	var oSpacerImg = document.getElementById("imgHeaderSpacer");
	if ( oSpacerImg )
	{
		oSpacerImg.style.width = document.body.clientWidth;
	}

	//Explicitly set tabindex on everything that has the taborder attribute set. 
	//iTabIndex is set in FWMain.master.
	$("*[settaborder]").attr("tabIndex", iTabIndex);

	//Load a navigation column photo-viewer image (scripts/NavImageViewer.js)
	LoadNavPhoto (iCurrentNavPhotoIndex);
	
	//Preload the navigation column photo-viewer images (scripts/NavImageViewer.js);
	PreloadNavImages();

	tb_init(".thickbox");

	//FB.init("3f0ba1d70537bbf9381bca2bbb9f9a93", "xd_receiver.htm");
	
	if ("function" == typeof(Init))
	{
		Init();
	}
}


//Searches a dropdown for an option whose value is equal to the specified string and 
//returns its numeric index. If the option is not found, -1 is returned.
function GetDDLIndexOfValue( DDL, strSrchValue )
{
	var iIndex = -1;
	for ( i = 0; i < DDL.options.length; i++ )
	{
		if ( DDL.options[i].value == strSrchValue )
		{
			iIndex = i;
			break;
		}
	}
	return iIndex;
}


//Searches a dropdown for an option whose text is equal to the specified string and 
//returns its numeric index. If the option is not found, -1 is returned.
function GetDDLIndexOfText( DDL, strSrchValue )
{
	var iIndex = -1;
	for ( i = 0; i < DDL.options.length; i++ )
	{
		if ( DDL.options[i].text == strSrchValue )
		{
			iIndex = i;
			break;
		}
	}
	return iIndex;
}

function IsEmpty ( oInput )
{
	return ((null == oInput) || ($(oInput).val().replace( /\s/g, "" ).length == 0));
}

///Given a field object, determines whether the field's value seems
///to be a valid email address. Returns true if so, false if not.
function ValidateEmail ( oField )
{
	var bOKToSubmit = true;
	
	if ( IsEmpty(oField) ||																								//strip whitespace and check for valid input
		(oField.value.length < 6 ) ||																							//check for at least 6 chars
		(oField.value.indexOf(".") < 3) ||																				//check for . in position 3 or later.
		(oField.value.indexOf("@") < 1) )																					//check for @ in position 1 or greater.
	{
		bOKToSubmit = false;
		alert( "Please enter a valid email address before submitting")
		oField.select();
	}

	return bOKToSubmit;	
}


///Creates the "lowest common denominator" of a name by stripping 
///extraneous characters and common words from it, and replacing
///spaces with underscores.
function ScrunchName ( strName )
{
	//strip punctuation & connecting words
	strName = strName.replace( /^the\s+|,\s+the$|[^_\w\s\-]|\b(and|on|of|the|her|his)\b/gi, "" );

	//turn single or multiple spaces/underscores into single underscores
	strName = strName.replace( /( |_)+/g, "_" );

	return strName;
}


//applies some basic URL-validity tests to a string and returns true if the value passes,
//false if the string doesn't seem to be a valid URL.
function IsValidURL ( strURL )
{
	var bRet = false;
	strURL = strURL.replace( /\s/g, "" );
	
	//test to see if URL field contains valid input.
	if ( strURL &&
		( 
			( strURL.charAt(0) == "/" && strURL.length > 1 ) ||
			( strURL.substring( 0, 7 ).toLowerCase() == "http://" && strURL.length > 7 ) ||
			( strURL.substring( 0, 8 ).toLowerCase() == "https://" && strURL.length > 8 ) 
		)
	)
	{
		bRet = true
	}

	return bRet;
}


//Attempts to split the name of an element apart and return the ID of the object it contains data for.
//If the element name is delimited with the specified character (ie Row_1), the ID is the last term. Otherwise, the ID
//the entire name.
function GetItemId ( oSrcEl, delimiter )
{
	if (null == delimiter)
	{
		delimiter = "_";
	}

	var arrSrcElParts;
	var iItemID = DEFAULT_ITEM_ID;

	if ( oSrcEl.name )
	{
		arrSrcElParts = oSrcEl.name.split( delimiter );
	}
	else if ( oSrcEl.id )
	{
		arrSrcElParts = oSrcEl.id.split( delimiter );
	}
	else
	{
		arrSrcElParts = null;
	}

	return (null == arrSrcElParts) ? -1 : arrSrcElParts[arrSrcElParts.length - 1]
}


//Given the ID of an Item, returns a handle to the table row that contains its data.
function GetTableRow ( oTbl, iItemID )
{
	var oRet = null;
	for ( i = 0; i<oTbl.rows.length; i++ )
	{
		if ( oTbl.rows[i].id == "Row_" + iItemID )
		{
			oRet = oTbl.rows[i];
			break;
		}
	}
			
	return oRet;
}


//Checks to see if the specified table row's contents have changed. If they have, and the 
//row being tested is the last row of the table, add a blank row to the bottom of the table.
//IMPORTANT: Each table using this function must implement IsRowEmpty, RowDataStruct and AddTableRow
function UpdateRowStatus ( oSrcEl )
{
	var iItemID = GetItemID( oSrcEl );
	var oRow = GetParentObject( oSrcEl, "tr", true );
	var oTbl = GetParentObject( oRow, "table", false );
	if ( !oTbl.IsRowEmpty( oRow ) )
	{
		//add a blank row at the end of the table when the last row changes.
		if ( IsLastTableRow( oRow ) )
		{
			AddEmptyTableRow( oTbl );
		}
	}
}


//determines whether or not the specified row is the last row of its parent table
function IsLastTableRow ( oRow )
{
	var oTbl = GetParentObject( oRow, "table", true );
	return oRow.sectionRowIndex == oTbl.tBodies[0].rows.length - 1;
}


//Adds an empty table row to a dynamic table
//IMPORTANT: Each table using this function must implement oRowDataStruct and AddTableRow
function AddEmptyTableRow( oTbl )
{
	oTbl.AddTableRow( new oTbl.RowDataStruct() );
}


//Determines whether the row before the given row is empty or not, using the individual table's IsRowEmpty function. 
//IMPORTANT: Each table using this function must implement IsRowRempty, GetPreviousRow, oRowDataStruct and AddTableRow
function IsPreviousRowEmpty( oRow )
{
	var bRet = false;
	var oTbl = GetParentObject( oRow, "table", true );
	
	//Only test if the row being queried is numbered 2 or higher (row 0 is the header)
	if ( oRow.sectionRowIndex > 0 )
	{
		//previous row exists. Test to see if it is empty
		bRet = oTbl.IsRowEmpty( oTbl.GetPreviousRow( oRow ) );
	}
	return bRet;
}


//Creates an empty new table cell, appends it to the end of the given row and returns a handle to it.
function AppendNewTableCell ( oRow )
{
	return oRow.insertCell( -1 );
}


//Walks up the element tree looking for an ancestor with a specific tag name
//Returns a handle to that element if found, or null if the body tag is reached.
//If bTestSrcElement is true, the source element is tested. If not, the source
//element is skipped and its parent element is tested.
function GetParentObject ( oEl, strSeekTagName, bTestSrcElement )
{
//alert("GetParentObject:" + oEl + "," + strSeekTagName + ", " + bTestSrcElement);
	var oRet;
	strSeekTagName = strSeekTagName.toLowerCase();
	
	//If this is the first iteration, test the input element. If it's body, end now.
	//If not, evaluate the parent element.
	if (!bTestSrcElement)
	{
		oEl = oEl.parentNode
	}
//alert("Testing: " + oEl.tagName + "\nSeeking: " + strSeekTagName);
	//lowercase the tag name of the element we're testing for use in comparisons.
	var strTestTagName = oEl.tagName ? oEl.tagName.toLowerCase() : "";

	if ( strTestTagName == strSeekTagName )
	{
//alert("hit");		
		oRet = oEl;
	}
	else if ( strTestTagName == "body" )
	{
		oRet = null;
	}
	else
	{
		oRet = GetParentObject( oEl, strSeekTagName, false );
	}

	return oRet;
}


//Deletes the table row that it is called from. If the row being deleted is the last of the table,
//and the previous row is empty, adds a new blank row to the end of the table.
//IMPORTANT: Each page that uses this must implement IsRowEmpty and AddEmptyTableRow
function DelTableRow ( oSrcEl, bConfirm )
{
	var bContinue = true;
	if ( bConfirm )
	{
		bContinue = confirm("Are you sure you want to delete this item?\n" +
		"(Changes and deletions will not be saved until you click Submit.)");
	}
	
	if (bContinue)
	{
		var oRow = GetParentObject( oSrcEl, "tr", true );
		var oTbl = GetParentObject( oRow, "table", true );

		//ensure that there is always one blank line at the bottom of the table
		if ( IsLastTableRow( oRow ) && !IsPreviousRowEmpty( oRow ) )
		{
			AddEmptyTableRow( oTbl );
		}
		
		//delete row
		oTbl.deleteRow( oRow.rowIndex );
	}
}


//scans the source table for rows that need to be saved and inserts a comma-delimited list of 
//their IDs into the target element.
function PopulateItemList( oSourceTable )
{
	var strList = "";
	
	//Walk all table rows
	for ( i = 0; i < oSourceTable.rows.length; i++ )
	{
		var oRow = oSourceTable.rows[i];
		var iRowID = GetItemId( oRow );
		if ( iRowID != DEFAULT_ITEM_ID && !oSourceTable.IsRowEmpty( oRow ) )
		{
			strList += "," + iRowID;
		}
	}
	strList = strList.substr(1);
	oSourceTable.oItemList.value = strList;
}


function ShowShortArticle ( iArticleID )
{
	oShortDiv = document.getElementById( iArticleID + "_Short" );
	if ( oShortDiv )
		oShortDiv.style.display = "";
	
	oLongDiv = document.getElementById( iArticleID + "_Long" );
	if ( oLongDiv )
		oLongDiv.style.display = "none";
}


function ShowFullArticle ( iArticleID )
{
	oShortDiv = document.getElementById( iArticleID + "_Short" );
	if ( oShortDiv )
	{
		oShortDiv.style.display = "none";
	}
	
	oLongDiv = document.getElementById( iArticleID + "_Long" );
	if ( oLongDiv )
	{
		oLongDiv.style.display = "";
	}
}


function SetWatchList ( oSrcElement )
{
  var action, buttonChecked;
  action = oSrcElement.checked ? "add" : "remove";
  var bandID = $(oSrcElement).attr("BandId"); 
  $.get("SetWatchList.aspx", { Action: action, BandId: bandID },
    function(data) {
      if (data.indexOf("Success") == -1)
      {
        //Update failed. Alert the user and reset the checkbox to its initial state.
        alert("Sorry, your change could not be saved.\n\n" + data);

        if (oSrcElement.checked)
        {
          oSrcElement.attr("checked", false);
        }
        else
        {
          oSrcElement.attr("checked", "checked");
        }
      }
      else
      {
        //Save succeeded. Check any other boxes for this band and add the "Watched" style to the band's links.
        if ("add" == action)
        {
          $("a[@BandId='" + bandID + "']").addClass("WatchedBand");
          $("input[@type='checkbox'][@BandId='" + bandID + "']").attr("checked", "checked");
        }
        else
        {
          $("a[@BandId='" + bandID + "']").removeClass("WatchedBand");
          $("input[@type='checkbox'][@BandId='" + bandID + "']").attr("checked", false);
        }
      }
    });
}


function CompareDates ( oDate1, oDate2 )
{
	var iRet = 0;
	var iTemp = 0;
	
	//Compare years. If they're different, our dates are different. Return and stop comparing
	iTemp = Compare( oDate1.getFullYear(), oDate2.getFullYear() );
	if ( iTemp != 0 )
	{
		return iTemp;
	}
	
	//Compare months. If they're different, our dates are different. Return and stop comparing
	iTemp = Compare( oDate1.getMonth(), oDate2.getMonth() );
	if ( iTemp != 0 )
	{
		return iTemp;
	}
	
	//Compare days and return the result.
	iTemp = Compare( oDate1.getDate(), oDate2.getDate() );
	return iTemp;
}


//Compare two values. Return 1 if the second is larger than the first, -1 if second is smaller than first, 0 if equal
function Compare ( v1, v2 )
{
	var iRet = 0;
	if ( v2 > v1 )
	{
		iRet = 1;
	}
	else if ( v2 < v1 )
	{
		iRet = -1;
	}
	return iRet;
}


//Given the name of a radio button set, returns the value of the checked button.
//If the second argument is true (false by default), also sets focus to the checked button.
function GetRadioButtonValue ( strRadioName, bSetFocus )
{
	strRet = null;
	
	oRadio = document.all( strRadioName )
	{
		for ( i = 0; i < oRadio.length; i++ )
		{
			if ( oRadio[i].checked )
			{
				if ( bSetFocus )
				{
					oRadio[i].focus();
				}
				strRet = oRadio[i].value;
				break;
			}
		}
	}

	return strRet;
}


//Set up intial and alternate display and tooltip text for a toggle button.
function SetupToggleButton ( oButton, InitialValue, AltValue, InitialTooltip, AltTooltip )
{
	if ( oButton )
	{
	//expando properties to save values for later use
		oButton.InitialValue = InitialValue;
		oButton.AltValue = AltValue;
		oButton.InitialTooltip = InitialTooltip;
		oButton.AltTooltip = AltTooltip;
		
		//set initial values on the button
		oButton.value = InitialValue;
		oButton.title = InitialTooltip;
	}
}


//Set up initial and alternate src and tooltip values for a toggle icon (image)
function SetupToggleIcon ( oIcon, InitialSrc, AltSrc, InitialTooltip, AltTooltip )
{
	//expando properties to save values for later use
	oIcon.InitialSrc = InitialSrc;
	oIcon.AltSrc = AltSrc;
	oIcon.InitialTooltip = InitialTooltip;
	oIcon.AltTooltip = AltTooltip;
	
	//set initial values
	oIcon.src = InitialSrc;
	oIcon.title = InitialTooltip;
}


function ToggleEmailIcon ( oEl )
{
	if ( oEl.IsActive == "no" )
	{
		oEl.IsActive = "yes";
		oEl.parentElement.className += " Highlighted";
		oEl.title = oEl.AltTooltip
	}
	else
	{
		oEl.IsActive = "no";
		oEl.parentElement.className = "Item";
		oEl.title = oEl.InitialTooltip;
	}
}


function InitEmailIcons (  )
{
	oColl = document.getElementsByTagName("img");
	for ( i = 0; i < oColl.length; i++ )
	{
		if ( oColl[i].id.indexOf("img_Email_") > -1 )
		{
			SetupToggleIcon( oColl[i], "Images/email.jpg", "Images/email.jpg", 
				"Click here to add this show to the list you wish to email.", "Click here to remove this show from the list you wish to email." );
		}
	}
}


function SubmitForm ( strAction )
{
	var bContinue = true;
	var oForm = document.forms[0];
	switch ( strAction.toLowerCase() )
	{
		case "chooseband" :
			/*
			oCombo = document.getElementById("NavColumnBandCombo_Text")
			location.href="<%= ForceWeb.Core.SiteSettings.GetResourceString("PAGE_BAND_INFO") %>?Band=" + ScrunchName(oCombo.value);
			*/
			break;
		case "emailshows" :
			var iShows = GetHighlightedShows();
			if ( iShows == 0 )
			{
				bContinue = false;
				alert( "You have not selected any shows to send.\n\nPlease select shows from the list at right by clicking " +
					"their email icons and then click Send again." );
			}
			if ( document.forms[0].tbxEmailShows.value.length == 0 )
			{
				bContinue = false;
				alert( "You have not specified who these shows should be sent to.\n\nPlease enter 1-" +
					"<%= ForceWeb.EmailShows.MaxEmailRecipients %> email addresses and/or site usernames (CForce, for instance) " +
					"into the box and click Send again." );
			}
			
			if ( bContinue )
			{
				oForm.action = "EmailShows.aspx";
				oForm.submit();
			}
			break;
		default :
//			alert( "SubmitForm must be called with an argument. Doing Nothing." );
			break;
	}
}


function GetHighlightedShows (  )
{
	var iShowsFound = 0;
	oColl = document.getElementsByTagName("img");
	oShowList = document.getElementById("hdnShowIdList");
	oShowList.value = "";
	for ( i = 0; i < oColl.length; i++ )
	{
		if ( oColl[i].id.indexOf("img_Email_") > -1 && oColl[i].IsActive == "yes" )
		{
			iShowsFound++;
			oShowList.value += GetItemId( oColl[i] ) + ",";
		}
	}
	if ( oShowList.value.length > 0 )
	{
		oShowList.value = oShowList.value.substring( 0, oShowList.value.length - 1);
	}
	
	return iShowsFound;
}


function isInArray (arr, value, ignoreCase)
{
	return (findInArray(arr, value, ignoreCase) > -1);
}


function findInArray (arr, value, ignoreCase)
{
	var ret = -1;
	var arrayValue, searchValue;
	for (i = 0; i < arr.length; i++)
	{
		if (ignoreCase)
		{
			arrayValue = arr[i].toLowerCase();
			searchValue = value.toLowerCase();
		}
		else
		{
			arrayValue = arr[i];
			searchValue = value;
		}
		
		if (arrayValue == searchValue)
		{
			ret = i;
			break;
		}
	}
		
	return ret;
}


//Queries a web service for a band's Info text and photo counts (icon photo, photo albums & total # of photos),
//and populates the specified Wrapper elements with the results.
function FillInfoAndImageFields( bandId, bandInfoWrapper, imagesWrapper, bandCombo )
{
	//Insert loading animation while AJAX calls are happening.
	$(imagesWrapper).html("<img src=\"Images/loadingAnimation.gif\" width=\"75\" align=\"absmiddle\">");

	//Fill Permanent Info field and photo information

	$.ajax({
		type: "POST",
		url: "Lookup.asmx/GetBandInfo",
		data: "id=" + bandId,
		dataType: "xml",
		timeout: 3000,
		success: function(xml) {
			var name = "";
			var info = "";
			var iconURL = "";
			var photos = 0;
			var resultsFound = false;
			$(xml).each(function() {
				if ($("ID", this).text() != "0") { resultsFound = true; }
				name = $("Name_Storage", this).text();
				info = $("Info", this).text();
				iconURL = $("FullURL", this).text();
				photos = $("Photos", this).text();
			});
			//update the band's name 
			//(We might be here because the band form was submitted in the popup and the band name may have changed)
			$(bandCombo).val(name);

			$(bandInfoWrapper).html(info);
			$(imagesWrapper).html("");
			var imageCountText = resultsFound ? photos : "??";
			$(imagesWrapper).html("images: " + imageCountText);
			if (iconURL)
			{
				$(imagesWrapper).append("&nbsp;<img src=\"" + BAND_ICON_ICON_URL + "\" align=\"bottom\" " +
					"title=\"Band has an icon image that will appear on the calendar page next to their name.\" />");
			//TODO: Set up onhover viewing of thumbnail
			}
		},
		error: function() {
			$(imagesWrapper).html("lookup failed");
		}
	});
}


//Queries a web service for a band's link information and populates the specified Wrapper element with the results.
function GetBandLinkCount( bandId, linksWrapper )
{
	//Insert loading animation while AJAX calls are happening.
	$(linksWrapper).html("<img src=\"Images/loadingAnimation.gif\" width=\"75\" align=\"absmiddle\">");
	
	//Populate Links information
	$.ajax({
		type: "POST",
		url: "Lookup.asmx/GetBandLinks",
		data: "bandId=" + bandId,
		dataType: "xml",
		timeout: 3000,
		success: function(xml) {
			var type = "";
			var totalLinks = 0;
			var typesFound = 0;
			var resultsFound = false;
			var linkTypeID = 0;
			var linkTypeArray = new Array();

			$("BandLink", xml).each(function() {
				resultsFound = true;
				totalLinks++;
				
				linkTypeID = $("TypeID", this).text();
				if (!linkTypeArray[typesFound] || !(linkTypeArray[typesFound].typeID == linkTypeID))
				{
				  typesFound++;
				  o = new Object();
				  o.typeID = linkTypeID;
				  o.count = 1;
				  o.iconURL = $("IconURL", this).text();
				  o.typeName = $("TypeName", this).text();
				  linkTypeArray[typesFound] = o;
				}
				else
				{
				  linkTypeArray[typesFound].count++;
				}
			})

		  $(linksWrapper).html("");
		  $(linksWrapper).append("links: " + totalLinks);
		  for (i = 1; i <= typesFound; i++)
		  {
		    if (linkTypeArray[i].iconURL)
		    {
		      $(linksWrapper).append("&nbsp;<img src=\"" + linkTypeArray[i].iconURL + "\" align=\"bottom\" " +
					  "title=\"" + linkTypeArray[i].count + " " + linkTypeArray[i].typeName + " link(s)\">");
		    }
		  }
		},
		error: function(XMLHttpRequest, textStatus, errorThrown) {
			$(linksWrapper).html("lookup failed");
		}
	});
}