//Global array of functions to be called ondomready
var WishpotOnDomReadyFunctions = [];

/******************************************
 Common DOM Wrappers (FB + Regular DOM)
******************************************/
var WPJS = {
  CheckBoxGetChecked: function(cb){
    return cb.checked;
  },
  
  CheckBoxSetChecked: function(cb, value){
    cb.checked = value;
  },
  
  //Alert box with "Ok" button.  Title ignored for non-facebook apps.
  Alert: function(msg){
    return alert(msg);
  },
  
  AlertWithTitle: function(msg, title, timeout){
    var newdiv = document.createElement('div');
    WPJS.SetInnerXHTML(newdiv, msg);
    return WPJS._OpenAlertDialog(title, newdiv, null, timeout);
  },
  
  SetStyle: function(obj, name, value){
    obj.style[name] = value;
  },
  
  GetStyle: function(obj, name){
    return obj.style[name];
  },
  
  SetClass: function(obj, value){
    obj.className = value;
  },
  
  GetClass: function(obj){
    return obj.className;
  },
  
  //for select boxes
  GetSelectedIndex: function(obj){
    return obj.selectedIndex;
  },
  
  GetOptions: function(obj){
    return obj.options;
  },
  
  ClearOptions: function(select){
    while(select.options.length > 0)
    {
        select.remove(0);
    }
  },  
 
  CreateOption: function(name, value){
    return new Option(name, value);
  },
  
  AddOption: function(select, option){
    var options = select.options;
	options[options.length] = option;
  },
  
  //should work on any form element
  GetValue: function(select){
    return select.value;
  },
  
  //should work on any form element
  SetValue: function(obj, newValue){ 
    return (obj.value = newValue); 
  },
  
  //facebook requires full XHTML
  SetInnerXHTML: function(obj, text){
    obj.innerHTML = text;
  },
  
  SetSelected: function(obj, newValue){
    return (obj.selected = newValue);
  },
  
  GetSelected: function(obj){
    return obj.selected;
  },
  
  SetDisabled: function(obj, newValue){
    return (obj.disabled = newValue);
  },
  
  GetDisabled: function(obj){
    return obj.disabled;
  },
  
  GetClientWidth: function(obj){
    return obj.clientWidth;
  },
  
  GetClientHeight: function(obj){
    return obj.clientHeight;
  },
  
  //'top' is specified here for the sake of facebook iframes
  GoTo: function(url){
    window.top.location = url;
  },
  
  GetParentNode: function(obj){
    return obj.parentNode;
  },
  
  GetFirstChild: function(obj){
    return obj.firstChild;
  },
  
  GoToNewWindow: function(url, windowName, js_options){
    //if options aren't provided, try to do do what's most like openining a new tab.
    var opts = (js_options != null) ? js_options : '';
    return window.open(url, windowName, opts);
  },
  
  AddClass: function(obj, className){
    WPJS.WithJQuery(function(){
        $(obj).addClass(className);
    });
  },
  
  RunOnDomReady: function(func){
    WishpotOnDomReadyFunctions.push(func);
  },
  

  Debug: function(msg) {},






  _OpenAlertDialog: function(title, div_obj, width, auto_close_ms){
    WithJQueryUi(function(){
          var diag = jQuery(div_obj);
          if(typeof(width) == "undefined"){ width = 400; }
          diag.dialog({modal: true, autoOpen: false, title: title, width: width});
          diag.show();
          diag.dialog('open');
          if(typeof(auto_close_ms) != "undefined")
          {
            setTimeout(function(){diag.dialog('close');}, auto_close_ms);
          }        
          return diag;
      });
  },
  
  //Turns a div into a dismissable modal window
  AlertDialogDiv: function(title, div_id, width){
    return WPJS._OpenAlertDialog(title, document.getElementById(div_id), width);
  },
  
  _OpenConfirmationDialog: function(title, div_obj, onsuccesscallback){
      WithJQueryUi(function(){
          var diag = jQuery(div_obj);
          diag.show();
          diag.dialog({modal: true, 
            autoOpen: false, 
            title: title,
            buttons: {
              Cancel: function() {
                $(this).dialog('close');
              },
              Ok: function(){
                onsuccesscallback();
                $(this).dialog('close');
              }
           }
          });
          diag.dialog('open');
          return diag;
        });
  },
  
  //Creates a dialog out of an existing div
  ConfirmationDialogDiv: function(title, div_id, onsuccesscallback){
    var div = document.getElementById(div_id);
    WPJS._OpenConfirmationDialog(title, div, onsuccesscallback);
  },
  
  ConfirmationDialog: function(title, message, onsuccesscallback){
    var newdiv = document.createElement('div');
    WPJS.SetInnerXHTML(newdiv, message);
    WPJS._OpenConfirmationDialog(title, newdiv, onsuccesscallback); 
  },

  //events fired in response to facebook connect actions
  OnFbEvent: function(event, response, widget)
  {
   WPJS.Debug(event);
   WPJS.Debug(response);
   WPJS.Debug(widget);
      
   WPJS.WithJQuery(function(){
    var data = {response: response, event: event};
    if(typeof(widget) != 'undefined'){
      if(typeof(widget.dom) != 'undefined' && typeof(widget.dom.attributes) != 'undefined')
      {
        for(var i=0; i<widget.dom.attributes.length; i++)
        {
          var start = widget.dom.attributes[i].name.indexOf("data-wishpot-");
          if(start >= 0)
          {
            data[widget.dom.attributes[i].name.replace("data-wishpot-", "")] = widget.dom.attributes[i].value;
          }
        }
      }
      else if(typeof(widget.objid) != 'undefined')
      {
        data['objid'] = widget.objid;
        data['objtype'] = widget.objtype;
      }
    }
    jQuery.ajax({data: data, error: null, success: null, type: "POST", dataType: 'json', url: "/facebooklogger.axd"});
   });
  },

  WithJQuery: function(fn, attempt_num)
  {
	if(jQueryLoaded()) { fn(); }
	else
	{
	    if(!attempt_num) { attempt_num = 1; }
	    else { attempt_num+=1; }
	    WPJS.Debug("Attempting Jquery load: "+attempt_num);
	    if(attempt_num > g_MaxJqueryAttempts)
	    {
	        alert("Sorry, we were unable to load the necessary libraries to complete this operation.  Please try again, and if the problem continues, contact us.");
	        throw "Error loading JQuery after "+attempt_num+" tries.";
	    }
	    else { setTimeout(function(){WPJS.WithJQuery(fn, attempt_num);}, 1000); }
	}
  }
  
}

/******************************************
Common
******************************************/



document.getElementsByClassName = function(cl) {
var retnode = [];
var myclass = new RegExp('\\b'+cl+'\\b');
var elem = this.getElementsByTagName('*');
for (var i = 0; i < elem.length; i++) {
var classes = elem[i].className;
if (myclass.test(classes)) retnode.push(elem[i]);
}
return retnode;
}; 

//left in for backward-compatibility.  Eventually remove.
function GoTo(url) {  WPJS.GoTo(url); }

function FormatReturnUrl()
{
    var ruArg = 'ru=' + encodeURIComponent(window.location);
    return ruArg;
}

function DummyFunction() { return; }


//his a url, then the callback is optional
//his a url, then the callback is optional
function HitUrl(url, callback)
{
	var i=new Image(1,1);
	if(typeof(callback) == 'undefined')
	  callback = function() {DummyFunction();};
  i.onload = callback;
  i.onerror = callback;
	i.src=url;
}

var last_err = null;
function ReportError(err, url, line)
{
	try
	{
	    if(err == last_err && err != null){return true;}
	    last_err = err;
	    var msg = "" + err;
	    var err_url = window.location.href;
	    if (url != null) err_url = url;
	    var err_line = ""+line;
	    var url = "/cerr.aspx?msg=" + encodeURIComponent(msg) + "&url=" + encodeURIComponent(err_url) + "&line=" + err_line + "&stack=" + encodeURIComponent(stacktrace());
		HitUrl(url);
	}
	catch(ex2)
	{}
	
	//supress the eventual javascript error
    return true;
}


function AsyncErrHandler(ex, url, line)
{
	try{ ReportError(ex, url, line); }
	catch(ex2){}

	try{ alert("The asynchronous operation failed. Please try again later. \n["+ex+"]"); }
	catch(ex2){}
}

function JqueryAjaxErrHandler(XMLHttpRequest, textStatus, errorThrown) 
{
  return AsyncErrHandler(textStatus, window.location.href, errorThrown);
}

// This function returns a string that contains a "stack trace."
// FROM: http://examples.oreilly.com/jscript3/text/7-3.txt
function stacktrace() {
    var s = "";  // This is the string we'll return.
    //alert(stacktrace.caller.toString());
    // Loop through the stack of functions, using the caller property of
    // one arguments object to refer to the next arguments object on the
    // stack.
    try {
        for (var a = stacktrace.caller; a != null; a = a.caller) {
            // Add the name of the current function to the return value.
            s += funcname(a) + " <-- ";

            // Because of a bug in Navigator 4.0, we need this line to break.
            // a.caller will equal a rather than null when we reach the end 
            // of the stack. The following line works around this.
            if (a.caller == a) break;
        }
    } catch (ex) {
        //silent catch - in case we have no permission
    }
    return s;
}
// This function returns the name of a given function. It does this by
// converting the function to a string, then using a regular expression
// to extract the function name from the resulting code.
function funcname(f) {
    if (f == null) return "null?";
    var s = f.toString().match(/function (\w*)/)[1];
    if ((s == null) || (s.length == 0)) return "anonymous";
    return s + " (" + f.arguments + ")";
}


// Enable global error handling
window.onerror = function(err, url, line) {
    //skip errors that are not worth reporting
    var errstr = "";
    if(err != null) errstr = ""+err;
    if(errstr.indexOf("openx") >= 0 || errstr.indexOf("GA_google") >= 0 || errstr.indexOf("GS_google") >= 0 || errstr.indexOf("doubleclick") >=0 || errstr.indexOf("Error loading script") >=0) return true;
    return ReportError(err, url, line);
}

/*Prompt for permissions via facebook connect */
function FacebookPromptPermission(jsonPermissions, callbackFunc) {
    // Check if user has permission, if not invoke dialog.
    FB.login(function(response) {
        if (response.session) {
            if(typeof(callbackFunc) != 'undefined') callbackFunc();
        } else {
            //this condition should really never be hit... none of this js should draw if they're not logged in
            WPJS.Alert("You must be logged in via facebook connect to perform this operation.");
        }
    }, jsonPermissions);
}

/****************************
 JQuery loading
 ****************************/
var g_JqueryPresent = false;
var g_MaxJqueryAttempts = 30;

function jQueryLoaded(){  return (typeof(jQuery) != "undefined"); }
function jQueryUiLoaded(){ return (jQueryLoaded() && typeof(jQuery.ui) != "undefined")}

function WithJQueryUi(fn, attempt_num)
{
	if(jQueryUiLoaded())
	{
	    try{ fn(); }
	    catch(ex) { AsyncErrHandler(ex); }
	}
	else
	{
	    if(!attempt_num) { attempt_num = 1; }
	    else { attempt_num+=1; }
	    
	    if(attempt_num > g_MaxJqueryAttempts)
	    {
	        alert("Sorry, we were unable to load the necessary libraries to complete this operation.  Please try again, and if the problem continues, contact us.");
	        throw "Error loading JQuery UI after "+attempt_num+" tries.";
	    }
	    else { setTimeout(function(){WithJQueryUi(fn, attempt_num)}, 1000); }
	}
}

function CloseDialog(id)
{
  WithJQueryUi(function(){
    var diag = $('#'+id);
    diag.dialog();
    diag.dialog('close');
  });
}


/******************************************
NavTab
******************************************/

function TabOn(el)
{
	if(el.className == 'inactiveTab')
		el.className = 'inactiveTabHover';
	else if(el.className == 'activeTabC')
		el.className = 'activeTabCHover';
}
function TabOff(el)
{
	if(el.className == 'inactiveTabHover')
		el.className = 'inactiveTab';
	else if(el.className == 'activeTabCHover')
		el.className = 'activeTabC';
}

function SearchOn(el)
{
	if(el.className == 'searchOff')
		el.className = 'searchOn';
}
function SearchOff(el)
{
	if(el.className == 'searchOn')
		el.className = 'searchOff';
}

function BtnOn(el)
{
	if(el.className == 'blink')
		el.className = 'blinkHov';
	else if(el.className == 'link')
		el.className = 'linkHov';
}
function BtnOff(el)
{
	if(el.className == 'blinkHov')
		el.className = 'blink';
	else if(el.className == 'linkHov')
		el.className = 'link';
}

/******************************************
DateTime
******************************************/


function FormatDateTime(msecs, includeTime) 
{
	d = new Date();

	//localOffset = d.getTimezoneOffset() * 60000;
	localTime = msecs; // + localOffset;
        d.setTime(localTime); 

	res = (d.getMonth()+1) + "/" + d.getDate() + "/" + d.getFullYear();

	if(includeTime)
	{
		h = d.getHours();
        m = d.getMinutes();

        ampm = "AM";
        if(h > 11)
        {
	   		h = h - 12;
           	ampm = "PM";
        }
        if(h == 0)
           	h = 12;
        
        if(m < 10)
            ms = "0" + m;
        else
            ms = m.toString();

		res = res + " at " + h + ":" + ms + " " + ampm;
	}
	return res;
}


/******************************************
User
******************************************/

function GoFindUser(sk)
{
    GoTo("/public/users/find.aspx?sk=" + sk);
}



function GoDeleteFriend(uid)
{
    if(confirm('Are you sure you want to remove this friend?'))
    {
        GoTo("/my/actions.aspx?action=deletefriend&uid=" + uid);
    }
}

function Trim(s)
{
    return s.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}


/******************************************
Wish
******************************************/

function SetWish(wid,action)
{
    document.getElementById('WishIdInput').value=wid;
    document.getElementById('WishActionInput').value=action;
}
function ConfirmDeleteWish(url)
{
    if(confirm('Are you sure you want to delete this item?'))
    {
	GoTo(url);
    }
}
function GoArchiveWish(wid)
{
	GoTo("/my/actions.aspx?action=setstatus&status=purchased&wid=" + wid + "&" + FormatReturnUrl());
}
function GoUnarchiveWish(wid)
{
	GoTo("/my/actions.aspx?action=setstatus&status=unpurchased&wid=" + wid + "&" + FormatReturnUrl());
}
function GoDeleteWishComment(wid,cid)
{
    if(confirm('Are you sure you want to delete this comment?'))
    {
	GoTo("/my/actions.aspx?action=deletecomment&wid=" + wid + "&cid=" + cid);
    }
}
function GoFlagWishComment(wid,cid)
{
    if(confirm('Are you sure you want to mark this comment as spam and delete it?'))
    {
	GoTo("/my/actions.aspx?action=flaganddeletecomment&wid=" + wid + "&cid=" + cid);
    }
}


/*** Search tip ***/

function SearchBoxFocus(tb)
{
	if(tb.className != "searchBoxTip")
		return;

	tb.value = "";
	tb.className = "searchBox";
}

function ValidateSearch(tbid)
{
	var tb = document.getElementById(tbid);
	return(tb.className != "searchBoxTip");
}

//Deprecated... use ToggleBlockDisplay in wishpot_common instead.
function ToggleDisplay(id)
{
	var div = document.getElementById(id);
	if(div.style.display == "block")
		div.style.display = "none";
	else
		div.style.display = "block";
}

function ToggleDisplayAndFocus(id, focusEl)
{
    ToggleDisplay(id);

	var div = document.getElementById(id);
	if(div.style.display == "block")
        document.getElementById(focusEl).focus();
}

function SetOff(el)
{
	var cl = el.className;
	if(cl)
	{
		var pos = cl.indexOf(" on");
		if(pos >= 0 && (pos == cl.length-3))
			el.className = cl.substring(0, pos) + " off";
	}
}
function SetOn(el)
{
	var cl = el.className;
	if(cl)
	{
		var pos = el.className.indexOf(" off");
		if(pos >= 0 && (pos == cl.length-4))
			el.className = cl.substring(0, pos) + " on";
	}
}

function OpenReserveDialog(id, murl, mname, onClickCallback)
{
  var hasCallback = (typeof(onClickCallback) != 'undefined');
  
  //if there's no reserve dialog to open, but we defined a callback, just fire it.
  //this is for the case when someone clicks 'add to cart' on an already-reserved item
  if(document.getElementById(id) == null && hasCallback){ onClickCallback(); }
    
  WPJS.WithJQuery(function(){
        var reserveDiv = jQuery('#'+id);
        if(murl)
        {
          reserveDiv.find('div.forReserve').removeClass("forReserve").addClass("forBuy");
          reserveDiv.find('input.__murl').attr('value', murl);
          reserveDiv.find('input.__mname').attr('value', mname);
          reserveDiv.find('a.__murl').attr('href', murl);
        }
        if(hasCallback)
        {
          reserveDiv.find('div.forReserve').removeClass("forReserve").addClass("forBuy");
          //whether you skip or not, callback should fire 
          reserveDiv.find('.wishpot-reserve').click(onClickCallback);
          reserveDiv.find('a.__murl').attr('href', '#').attr('target', '').click(onClickCallback);
        }
    });
  WPJS.AlertDialogDiv('', id); 
}

function OpenReviewDialog(title, divid, uid, pid)
{
  WPJS.WithJQuery(function(){
    var url = WISHPOT_API_ROOT+"/ProductReview/Details/?uid="+uid+"&pid="+pid;
    jQuery.ajax({data: '', error: LoadReviewData, success: LoadReviewData, type: "GET", dataType: 'json', url: url});
    WPJS.AlertDialogDiv(title, divid);
  });
 
}

function LoadReviewData(req, textStatus)
{
  if(req && req.Id)
  {
    var f = jQuery("#WishpotReviewForm_"+req.ProductId);
    f.find("[name=SummaryInput]").val(req.Summary);
    f.find("[name=ReviewInput]").val(req.Text);
    f.find("[name=RatingInput]").val(req.Rating);
    f.find(".current-rating").attr("class", "current-rating "+WP_NUMBERS[req.Rating]+"-stars");
    SetExistingRating("WriteReviewDiv_"+req.ProductId+"_formValue");
  }
  else
  {
    WPJS.Debug("Could not find/load existing rating: "+textStatus);
  }
}

function BeginBuy(uid, wid, pid) {
    var url = '/ajax/bestoffer.aspx?uid=' + uid + '&wid=' + wid + '&pid=' + pid;
    var callback = function(data) { EndBuy(data, wid); }
    WPJS.WithJQuery(function(){
        jQuery.ajax({ data: '', error: JqueryAjaxErrHandler, success: callback, type: "GET", dataType: 'json', url: url });
    });
}
	
function EndBuy(data,wid) {
    OpenReserveDialog("popRes_" + wid, data.MerchantUrl, data.MerchantName);
}

// This function shows the reserve dialog but does not then navigate to the site after they accept/reject
// the option to reserve.  Optionally you can provide a callback that will fire instead.
function BeginBuyNoNavigate(wid, callback)
{
    var id = "popRes_" + wid;
    OpenReserveDialog(id, null, null, callback);
    
    //if they choose to reserve, make sure they don't change the page, otherwise
    //two-navigations occur and it causes confusion.  This sets the return url to the current page
    if(document.getElementById(id) != null)
    {
        WPJS.WithJQuery(function(){
            var reserveDiv = jQuery('#'+id);
            reserveDiv.find("input[name='ru']").attr('value', window.location.href);
        });
    } 
}


function ToggleAltPicPicker(id, altClass)
{
	SetAltThumbStyles(-1);
	
	var id = "AltPicPicker";
	var altClass = "AltPicPickerToggle";
	var textId = "AltPicPickerText";
	var el = document.getElementById(id);
	var tel = document.getElementById(textId);
	var altEls = ((altClass != null) ? document.getElementsByClassName(altClass) : null);
	if(el.style.display == "block")
	{
		el.style.display = "none";
		tel.innerHTML = "see more pictures";
		tel.style.visibility = "visible";
		for(var i = 0; i < altEls.length; i++)
			altEls[i].style.visibility = "visible";
	}
	else
	{
		el.style.display = "block";
		tel.innerHTML = "see item details";
		for(var i = 0; i < altEls.length; i++)
			altEls[i].style.visibility = "hidden";
	}
}

function GetPrefAltPic()
{
	return (document.getElementById("PrefPic").value * 1);
}
function SetPrefAltPic(idx)
{
	document.getElementById("PrefPic").value = idx;
}
function GetAltPicCount()
{
	return (document.getElementById("PicCount").value * 1);
}
function GetAltPicEl(idx)
{
	return document.getElementById("AltPic"+idx);
}
function GetAltThumbEl(idx)
{
	return document.getElementById("AltThumb"+idx);
}
function SetAltPic(idx)
{
	var picCount = GetAltPicCount();
	for(var i=0; i<picCount; i++)
	{
		var el = GetAltPicEl(i);
		if(i == idx)
			el.style.display = "block";
		else
			el.style.display = "none";
	}
}
function SetAltThumbStyles(tempSel)
{
	var picCount = GetAltPicCount();
	var pref = GetPrefAltPic();
	for(var i=0; i<picCount; i++)
	{
		var el = GetAltThumbEl(i);
		if(i == pref)
			el.className = "SelAltThumb";
		else if(i == tempSel)
			el.className = "TempSelAltThumb";
		else
			el.className = "AltThumb";
	}
}
function AltThumbMouseOver(idx)
{
	var pref = GetPrefAltPic();
	if(pref != idx)
	{
		var el = GetAltThumbEl(idx);
		el.className = "TempSelAltThumb";
	}
	SetAltPic(idx);
	document.getElementById("AltPicPickerText").style.visibility = "hidden";
}

function AltThumbMouseOut(idx)
{
	var pref = GetPrefAltPic();
	if(pref != idx)
	{
		var el = GetAltThumbEl(idx);
		el.className = "AltThumb";
	}
	SetAltPic(pref);
	document.getElementById("AltPicPickerText").style.visibility = "visible";
}
function AltThumbClick(idx)
{
	SetAltPic(idx);
	SetPrefAltPic(idx);
	ToggleAltPicPicker();
}

function GoResendVerificationMail()
{
    GoTo("/my/actions.aspx?action=resendmail");
}

function FindParentForm(el)
{
	while(el && (el.nodeName.toLowerCase() != "form"))
		el = el.parentNode;
		
	return el;
}

function SubmitForm(el)
{
    var form = FindParentForm(el);
    
	if(form)
		form.submit();
}


/** Messaging **/
function SetAction(element, action, confirmText)
{
    if(confirmText != null && confirmText.length > 0) 
    {
        if(!confirm(confirmText)) 
        {
            return false;
        } 
    }
    
    document.getElementById("Action").value = action;
    SubmitForm(element);
    return true;
}

function UpdateEveryoneChkBox() 
{
    var friendsChkBox = document.getElementById("AcceptFromFriendsInput");
    var everyoneChkBox = document.getElementById("AcceptFromEveryoneInput");
    
    if(!friendsChkBox.checked) 
    {
        everyoneChkBox.checked = false;
    }
    
    return true;
}

function UpdateFriendsChkBox()
{
    var friendsChkBox = document.getElementById("AcceptFromFriendsInput");
    var everyoneChkBox = document.getElementById("AcceptFromEveryoneInput");

    if(everyoneChkBox.checked) 
    {
        friendsChkBox.checked = true;
    }
    
    return true;
}


function GetChkBoxes()
{
    var retnode = [];
    var elements = document.getElementsByTagName('input');

    for(var i = 0; i < elements.length; i++)
    {
        if(elements[i].type == "checkbox") 
        {
            var id = elements[i].id;
            var l = id.length;
            
            if(id.substring(l - 9) == "msgchkbox") 
            {
                retnode.push(elements[i]);
            }
        }
    }
    
    return retnode;
}

function UpdateChkBoxes(allChkBox)
{
    var elements = GetChkBoxes();
    
    for(var i = 0; i < elements.length; i++)
    {
        elements[i].checked = allChkBox.checked;
    }
}

function AtLeastOneChecked()
{
    var elements = GetChkBoxes();
    var oneChecked = false;

    for(var i = 0; i < elements.length; i++)
    {
        if(elements[i].checked) 
        {
            oneChecked = true;
            break;
        }
    }
    
    return oneChecked;
}

function ConfirmDelete(el)
{
    if(AtLeastOneChecked())
    {
        if(confirm('Are you sure you want do delete these messages?')) 
        {
            SubmitForm(el);
        }
    }
    else 
    {
        alert('Please select the messages you want to delete');
    }
}

function IfCheckedSubmitForm(el)
{
    if(AtLeastOneChecked())
    {
        SubmitForm(el);
    }
    else 
    {
        alert('Please select the messages you want to delete');
    }
}


function GetListProperties(id, arrayOfListProperties)
{
    for (var i = 0; i < arrayOfListProperties.length; i++)
    {
        if (arrayOfListProperties[i].Id == id)
            return arrayOfListProperties[i];
    }
    
    return null;
}


function ToggleSelectCreateList(el, createNew)
{
    var form = FindParentForm(el);
    
    if(form)
    {
        var listSelectDiv = FindChildElementById(form, 'ListSelectDiv');
        var newListDiv = FindChildElementById(form, 'NewListDiv');
        var createNewList = form.CreateNewList;
    
        createNewList.value = createNew;
        if(createNew)
        {
            listSelectDiv.style.display = "none";
            newListDiv.style.display = "block";
        }
        else
        {
            newListDiv.style.display = "none";
            listSelectDiv.style.display = "block";
        }
    }
    
    return false;
}

function EnableListSelect(el)
{
    return ToggleSelectCreateList(el, false);
}

function EnableNewList(el)
{
    return ToggleSelectCreateList(el, true);
}

function SetListNameValidation(enable)
{
    window.Page_Validators[0].enabled = enable;
}

function UpdateWishProperties()
{
    var createNewList = WPJS.GetValue(document.getElementById('CreateNewList'));
    
    if(createNewList.toLowerCase() == "true")
    {
        var lt = WPJS.GetValue(document.getElementById('ListType'));
        var props = GetListProperties(lt, ListPicker_ListTypeProperties);
        
        // Retrieve the props.AccessType from UI selection
        props.AccessType = 0;
        for(var i = 0; i < 3; i++)
        {
            var atBtn = document.getElementById('La_' + i);
            if(WPJS.CheckBoxGetChecked(atBtn)) 
            {
                props.AccessType = atBtn.value;
                break;
            }
        }
        
        SetWishProperties(props, null);
    }
    else
    {
        var lid = WPJS.GetValue(document.getElementById('ListSelect'));
        var props = GetListProperties(lid, ListPicker_ListProperties);

        SetWishProperties(props, lid);
    }
    
    return false;
}


function SetWishProperties(props, listId)    
{    
    if(props == null) return;
    
    SetAvailable_WishAccessFormControl(props.AccessType);
        
	var priorityDiv = document.getElementById('PriorityPanel');
    if(props.SupportsPriority) 
        priorityDiv.style.display = "block";
    else  
        priorityDiv.style.display = "none";
    
    var recipientDiv = document.getElementById('RecipientPanel');
    if(props.SupportsRecipient) 
        recipientDiv.style.display = "block";
    else  
        recipientDiv.style.display = "none";
    
	var occasionDiv = document.getElementById('OccasionPanel');
    if(props.SupportsOccasion) 
        occasionDiv.style.display = "block";
    else  
        occasionDiv.style.display = "none";

	var notesDiv = document.getElementById('NotesPanel');
    if(props.SupportsNotes) 
        notesDiv.style.display = "block";
    else  
        notesDiv.style.display = "none";

	var reviewsDiv = document.getElementById('ReviewPanel');
    if(props.SupportsReviews) 
        reviewsDiv.style.display = "block";
    else  
        reviewsDiv.style.display = "none";

	var quantityDiv = document.getElementById('QuantityPanel');
    if(props.SupportsQuantity) 
        quantityDiv.style.display = "block";
    else  
        quantityDiv.style.display = "none";
        
    if (typeof(AlertProperties_NotifyListTypeChanged) != 'undefined')
		AlertProperties_NotifyListTypeChanged(props.EnableAlertsByDefault);
    
    if (typeof(ContributionProperties_SetPanelVisibility) != 'undefined')
		ContributionProperties_SetPanelVisibility(props.SupportsContributions);    
}


/* Given a block of HTML, turns all relative links into absolute ones, given the passed-in base url */
function MakeAbsoluteLinks(text, base_url)
{
  var url_with_slash = base_url;
  var url_no_slash = base_url;
  if(/\/$/.test(base_url))
    url_no_slash = base_url.substring(0, base_url.length-1);
  else
    url_with_slash = base_url+"/";
  
  //simple tricks for finding relative paths and replacing with absolute
  var regexps = [
    new RegExp(/(\shref=")(\S*)(")/gim),
    new RegExp(/(\shref=')(\S*)(')/gim),
    new RegExp(/(\ssrc=")(\S*)(")/gim),
    new RegExp(/(\ssrc=')(\S*)(')/gim),
    new RegExp(/(background-image: url\(")(\S*)("\))/gim),
    new RegExp(/(background-image: url\(')(\S*)('\))/gim),
    new RegExp(/(background-image: url\()(\S*)(\))/gim)
  ]
  
  var AbsoluteLink = new RegExp("http://|https://|mailto:", "gim");
  
  var ret_text = text;
  for(i=0; i<regexps.length; i++)
  {
    ret_text = ret_text.replace(regexps[i], function(m){
      var r = new RegExp(regexps[i]);
      var newUrl = r.exec(m)[2];
      if (newUrl.match(AbsoluteLink))
      {
        WPJS.Debug("["+i+"] Skipping, url already absolute: "+newUrl);
        return m;
      }
      
      newUrl = (/^\//.test(newUrl)) ? (url_no_slash+newUrl) : (url_with_slash+newUrl);
      return m.replace(regexps[i], "$1"+newUrl+"$3");
      
    });
  }
  return ret_text;
}

function AfterMoveCopy(operation, wid, api_response)
{
    CloseDialog('CopyMoveDiv_'+wid);
    $('button').removeClass('clicked');
    if(operation == "move" || operation == "delete")
    {
      $('#Wish_'+wid).slideUp(1000);
    }
    if(operation == "copy")
    {
       var d = WPJS.AlertWithTitle("Wish copied.", "Operation complete", 1000);
    }
}

function DoAjaxMoveCopy(form_obj)
{
  var op = WPJS.GetValue(form_obj["operation"]);
  var wid = WPJS.GetValue(form_obj["Wish.Id"]);
  var callback = function(data, textStatus){AfterMoveCopy(op, wid, data);};
  var url = "";
  
  if(op == "move"){ url = WISHPOT_API_ROOT+"Wish/Edit/"+wid;}
  else if(op == "copy"){ url = WISHPOT_API_ROOT+"Wish/Copy"; }

  jQuery.ajax({data: $(form_obj).serialize(), error: JqueryAjaxErrHandler, success: callback, type: "POST", dataType: 'xml', url: url});
}

function DoAjaxDelete(wid)
{
  var callback = function(data){AfterMoveCopy("delete", wid, data);}
  jQuery.ajax({data: '', error: JqueryAjaxErrHandler, success: callback, type: "POST", dataType: 'text', url: WISHPOT_API_ROOT+"/Wish/Delete/"+wid});
}

function DoAjaxSetDefaultListSort(lid)
{
  var sortValue = document.getElementById('SortSelect').value;
  var callback = function(data){AfterSetDefault();}
  var active = WPJS.GetStyle( document.getElementById('setDefaultSort'), "display");
  if( active != 'inline' )
  {
    sortValue = "";
  }

  jQuery.ajax({data: 'List.UserDefSort=' + sortValue, error: JqueryAjaxErrHandler, success: callback, type: "POST", dataType: 'text', url: WISHPOT_API_ROOT+"/List/Edit/"+lid});
}

function AfterSetDefault()
{
    ToggleDisplayByObject(document.getElementById('currentDefaultSort'), "inline");
    ToggleDisplayByObject(document.getElementById('setDefaultSort' ), "inline" );
}

function FindChildElementById(parent, id)
{
    var children = parent.childNodes;
    
    if(children != null)
    {
        for (var i = 0; i < children.length; i++) 
        {
            if(children[i].id == id) 
            {
                return children[i];
            }
            
            var el = FindChildElementById(children[i], id);
            if(el != null)
            {
                return el;
            }
        }
    }

    return null;
}

function EnsureEl(idOrEl)
{
	if(typeof(idOrEl) == "string")
		idOrEl = document.getElementById(idOrEl);
	return idOrEl;
}

function rgbToHex(rgbstring) {
	// RGB to HEX: "rgb(0, 70, 255)"
	if (rgbstring) {
		if (rgbstring.indexOf('rgb(') == -1) {
			return rgbstring;
		}
		var parts = rgbstring.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
		delete (parts[0]);
		for (var i = 1; i <= 3; ++i) {
		    parts[i] = parseInt(parts[i],0).toString(16);
		    if (parts[i].length == 1) parts[i] = '0' + parts[i];
		}
		var hexstring = parts.join('');
		return '#' + hexstring;	
	}
}

function normalizeStyleValues(string,optionalReferenceObj) {
	// RGB to HEX: "rgb(0, 70, 255)"
	if (string.indexOf('rgb') != -1) {
		var parts = string.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
		delete (parts[0]);
		for (var i = 1; i <= 3; ++i) {
		    parts[i] = parseInt(parts[i],0).toString(16);
		    if (parts[i].length == 1) parts[i] = '0' + parts[i];
		}
		var hexString = parts.join('');
		return '#' + hexString;
	}
	// Color values already in HEX
	else if (string.indexOf('#') != -1) {
		return string;
	}
	// Position strings and pixel values to percentages
	else if (string.indexOf('px') != -1 && optionalReferenceObj) {
		var objheight = jQuery(optionalReferenceObj).height();
		var objWidth = jQuery(optionalReferenceObj).width();
		var x = string.split(' ')[0];
		var y = string.split(' ')[1];
		x = x == '0px' ? '0%' : x == objWidth + 'px' ? '100%' : x == (objWidth/2) + 'px' ? '50%' : x;
		y = y == '0px' ? '0%' : y == objheight + 'px' ? '100%' : y == (objheight/2) + 'px' ? '50%' : y;
		string = x + ' ' + y;
		return string;
	}
	else {
		string = string.replace(/top/g,'0%');
		string = string.replace(/bottom/g,'100%');
		string = string.replace(/left/g,'0%');
		string = string.replace(/right/g,'100%');
		string = string.replace(/center/g,'50%');
		return string;
	}
}


/**
 Scripts below here were ordered this way so that they worked on both Wishpot and Facebook.  
 This distinction isn't as important anymore.
 **/

//Toggle the display of an object (not an id) between block and none
function ToggleBlockDisplay(obj) {
    return ToggleDisplayByObject(EnsureEl(obj), "block");
}

function ToggleDisplayByObject(obj, displaytype) {
    if (WPJS.GetStyle(obj, "display") == displaytype)
        WPJS.SetStyle(obj, "display", "none");
    else
        WPJS.SetStyle(obj, "display", displaytype);
}

function ShowObject(obj)
{
  WPJS.SetStyle(EnsureEl(obj), "display", "");
}

function ToggleEnabled(obj) {
    WPJS.SetDisabled(obj, !WPJS.GetDisabled(obj));
}

/**
A validator function that matches the signature of an ASP validator for
use with things that require a number to be positive.
**/
function ValidatePositiveNumeric(source, args) {
    //default to true
    args.IsValid = true;

    //always needs to be numeric, regardless of what type of alert
    var numericValue = parseFloat(args.Value);
    if (isNaN(args.Value) || numericValue <= 0) {
        args.IsValid = false;
        WPJS.SetInnerXHTML(source, "Value must be a number greater than zero.");
        return;
    }
}

/** Given an image, scales it to fit inside our 150x150 product box **/
function fitToProductBox(img) {
    if (null == img) return;
    var heightBigger = (WPJS.GetClientHeight(img) > WPJS.GetClientWidth(img));

    if (heightBigger) {
        WPJS.SetStyle(img, "width", "150px");
        if (WPJS.GetClientHeight(img) > 0)
            WPJS.SetStyle(img, "marginTop", Math.round((150 - WPJS.GetClientHeight(img)) / 2) + "px");
    }
    else {
        WPJS.SetStyle(img, "height", "150px");
        if (WPJS.GetClientWidth(img) > 0)
            WPJS.SetStyle(img, "marginLeft", Math.round((150 - WPJS.GetClientWidth(img)) / 2) + "px");
    }
}

/** Used so we can easily style inputs of different types */
function AppendInputTypeClasses() 
{  
	if (!document.getElementsByTagName )   
		return;  
	var inputs = document.getElementsByTagName('input');  
	var inputLen = inputs.length;  
	for(var i=0;i<inputLen;i++) 
	{   
		if(inputs[i].getAttribute('type'))    
			inputs[i].className += ' '+inputs[i].getAttribute('type');  
	}
}

function DrawRating(itemId, rating) {
    var ratingDiv = document.getElementById('RatingString_' + itemId);
    if (rating == 0) WPJS.SetInnerXHTML(ratingDiv, "<b>No Rating</b>");
    else if (rating == 1) WPJS.SetInnerXHTML(ratingDiv, "<b>I hate it!</b>");
    else if (rating == 2) WPJS.SetInnerXHTML(ratingDiv, "<b>I don't like it</b>");
    else if (rating == 3) WPJS.SetInnerXHTML(ratingDiv, "<b>I like it</b>");
    else if (rating == 4) WPJS.SetInnerXHTML(ratingDiv, "<b>I really like it</b>");
    else if (rating == 5) WPJS.SetInnerXHTML(ratingDiv, "<b>I love it!</b>");
}

function SetExistingRating(itemId) {
    var rating = WPJS.GetValue(document.getElementById('RatingInput_' + itemId));
    DrawRating(itemId, rating);
}

function SetRating(itemId, rating) {
    WPJS.SetValue(document.getElementById('RatingInput_' + itemId), rating);
}

function JumpToPage() {
    var baseUrl = document.getElementById('PagerBaseUrl').value;
    var page = document.getElementById('JumpToPageInput').value;
    WPJS.GoTo(baseUrl + page);
  }

  function SortChange() {
    var baseUrl = document.getElementById('SorterBaseUrl').value;
    var sortValue = document.getElementById('SortSelect').value;
    WPJS.GoTo(baseUrl + sortValue);
  }

function WishStatusSelectionChange() {
  var baseUrl = document.getElementById('WishStatusSelectorBaseUrl').value;
  var sortValue = document.getElementById('WishStatusSelectorSelect').value;
  WPJS.GoTo(baseUrl + sortValue);
}

function UpdateButtonCode(buttonLink, textAreaName)
{
  var newSrc = jQuery(buttonLink).children('img.addButton').attr('src');
  textAreaName = EnsureEl(textAreaName);
  jQuery(textAreaName).val(jQuery(textAreaName).val().replace(/img src=".+"/i, "img src=\""+newSrc+"\""));
}

function VolusionCartAdd(siteUrl, sku, wid) {
    try {
        BeginBuyNoNavigate(wid, function () {
            var w = WPJS.GoToNewWindow('http://' + siteUrl + '/ShoppingCart.asp?ProductCode=' + sku, 'VolusionCart');
            try {
                w.focus();
            } catch (ex) { WPJS.Debug(ex); } //swallow in facebook
        });
    } catch (ex) { WPJS.Debug(ex); } //swallow in facebook
}


var WP_MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var WP_DAYNAMES = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var WP_NUMBERS = ["zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];




