//JavaScript file

//JavaScript Based Order Object for getting and setting Order based info for access at any time from JavaScript.
function createpcorderobj()
{
  this.storedomainid=null;
  this.storecode=null;
  this.storename=null;
  this.storecompanyname=null;

  this.orderid=null;
  this.orderuuid=null;
  this.ordertotal=null;

  this.hasbackorder=null;
  this.hasdropship=null;
  this.orderdiscount=null;
  this.productdiscount=null;
  this.usedcredit=null;
  this.totalshipping=null;
  this.totalhandlingcost=null;
    this.totalshipandhandling=null; //should be set to (totalshipping + totalhandlingcost) when used
  this.totalproducttax=null;

  this.memberid=null;
  
  this.customerismember=null;
  
  this.protocol = document.location.protocol;
  this.issecure = ("https:" == this.protocol) ? true : false;

  this.viewproduct=null;
  //this.viewproductid=null;
  //this.viewproductsku=null;
  //Arrays
  this.cartprodlist=new Array();// should contain an array of Product Objects. Each object should have the following properties: [productid,sku,qty,subtotal]
  this.cartprod_idlist=new Array();
  this.cartprod_skulist=new Array();
  this.cartprod_namelist=new Array();
  this.cartprod_pricelist=new Array();
  this.cartprod_qtylist=new Array();
  this.cartprod_subtotallist=new Array();
  this.finalizeordereventlist=new Array(); // Array of EVENTS to trigger when the FINISH order button is pressed on the Order Review Page
  
  //Property list
  //this.propertylist="propertylist,storedomainid,orderid,memberid,ordertotal,viewproductid,viewproductsku,cartprod_idlist,cartprod_skulist,cartprod_qtylist,cartprod_subtotallist";
  
  
  //Setters and Getters
  this.getprotocol=function() { return this.protocol; }

  this.getissecure=function() { return this.issecure; }
  
  this.getstoredomainid=function() { return this.storedomainid; }
  this.setstoredomainid=function(sdid) { this.storedomainid=sdid; }
  
  this.getstorecode=function() { return this.storecoded; }
  this.setstorecode=function(storecodeval) { this.storecode=storecodeval; }

  this.getstorename=function() { return this.storename; }
  this.setstorename=function(storenameval) { this.storename=storenameval; }
  
  this.getstorecompanyname=function() { return this.storecompanyname; }
  this.setstorecompanyname=function(storecompanynameval) { this.storecompanyname=storecompanynameval; }
  
  this.getorderid=function() { return this.orderid; }
  this.setorderid=function(oid) { this.orderid=oid; }
  
  this.getorderuuid=function() { return this.orderuuid; }
  this.setorderuuid=function(uuid) { this.orderuuid=uuid; }

  this.getordertotal=function() { return this.ordertotal; }
  this.setordertotal=function(otot) { this.ordertotal=otot; }
    

      this.gethasbackorder=function() { return this.hasbackorder; }
      this.sethasbackorder=function(boflag) { this.hasbackorder=boflag; }
    
      this.gethasdropship=function() { return this.hasdropship; }
      this.sethasdropship=function(dropshipflag) { this.hasdropship=dropshipflag; }
      
      this.getorderdiscount=function() { return this.orderdiscount; }
      this.setorderdiscount=function(orddisc) { this.orderdiscount=orddisc; }
      
      this.getproductdiscount=function() { return this.productdiscount; }
      this.setproductdiscount=function(proddisc) { this.productdiscount=proddisc; }
    
      this.getusedcredit=function() { return this.usedcredit; }
      this.setusedcredit=function(usedcred) { this.usedcredit=usedcred; }
      
      this.gettotalshipping=function() { return this.totalshipping; }
      this.settotalshipping=function(totship) { this.totalshipping=totship; } 
      
      this.gettotalhandlingcost=function() { return this.totalhandlingcost; }
      this.settotalhandlingcost=function(tothandling) { this.totalhandlingcost=tothandling; } 
     
          this.gettotalshipandhandling=function() { return this.totalshipandhandling; }
          this.settotalshipandhandling=function(totshipandhandling) { this.totalshipandhandling=totshipandhandling; } 
     
      this.gettotalproducttax=function() { return this.totalproducttax; }
      this.settotalproducttax=function(totprodtax) { this.totalproducttax=totprodtax; } 
      

  this.getmemberid=function() { return this.memberid; }
  this.setmemberid=function(memid) { this.memberid=memid; }
  
  this.getismember=function() { return this.customerismember; }
  this.setismember=function(ismemflag) { this.customerismember=ismemflag; }
  
  //Viewed Product Details
  this.getviewproductid=function() { return this.viewproductid; }
  this.setviewproductid=function(pid) { this.viewproductid=pid; }
  
  this.getviewproductsku=function() { return this.viewproduct.sku; }
  this.setviewproductsku=function(psku) { this.viewproductsku=psku; }

  //Bill Address
  this.getbilladdress=function() { return this.billaddress; }
  this.setbilladdress=function(billjson) { this.billaddress=billjson; }
  this.billaddress={memberaddressid:"", addresstype:"", addressname:"", primaryaddress:"", memberid:"", firstname:"", lastname:"", street1:"", street2:"", city:"", stateid:"", zipcode:"", country:"", dayphone:"", dayextension:"", nightphone:"", nightextension:"", fax:"", email:"", companyname:"", clonemaid:"", statecode:"", statename:""}
  

  //Events
  this.getevents_finalizeorder=function() { return this.finalizeordereventlist; }
  this.appendeventto_finalizeorder=function(evnt) { this.finalizeordereventlist.push(evnt); }
  this.prependeventto_finalizeorder=function(evnt) { this.finalizeordereventlist.unshift(evnt); }
  this.clearevents_finalizeorder=function() { this.finalizeordereventlist=new Array(); }
  this.runevents_finalizeorder=function()
       {
          for(var i=0; i<this.getevents_finalizeorder().length; i++)
          {
            eval(this.getevents_finalizeorder()[i]);
            //try { eval(this.getevents_finalizeorder()[i]); } catch(e) { alert("There was a problem initiating pcorderobj event - "+this.getevents_finalizeorder()[i]); debugResponse(e); }
          }
       }
  
  this.setviewproduct=function(prodobj)
      {
          //make a prototype product object then set the values
          var thisnewprod=new createpcproductobj;
          thisnewprod.setproductid(prodobj.productid);
          thisnewprod.setsku(prodobj.sku);
          thisnewprod.setname(prodobj.name);
          thisnewprod.setprice(prodobj.price);
          thisnewprod.setqty(prodobj.qty);
          thisnewprod.setsubtotal(prodobj.subtotal);
          this.viewproduct=thisnewprod;
      }
  this.getviewproduct=function() { return this.viewproduct; }

  this.addproduct=function(prodobj)
       {
          //make a prototype product object then set the values
          var thisnewprod=new createpcproductobj;
          thisnewprod.setproductid(prodobj.productid);
          thisnewprod.setsku(prodobj.sku);
          thisnewprod.setname(prodobj.name);
          thisnewprod.setprice(prodobj.price);
          thisnewprod.setqty(prodobj.qty);
          thisnewprod.setsubtotal(prodobj.subtotal);
          
          //update the helper lists/arrays.
          this.cartprodlist.push(thisnewprod);
          this.cartprod_idlist.push(thisnewprod.getproductid());
          this.cartprod_skulist.push(thisnewprod.getsku());
          this.cartprod_namelist.push(thisnewprod.getname());
          this.cartprod_pricelist.push(thisnewprod.getprice());
          this.cartprod_qtylist.push(thisnewprod.getqty());
          this.cartprod_subtotallist.push(thisnewprod.getsubtotal());
       } //Expects a JSON with relevant properties available.
  
  //Arrays (returns an array with GET and expects an array with SET)
  this.getcartprodlist=function() { return this.cartprodlist; }
  this.setcartprodlist=function(prodarray) { this.cartprodlist=prodarray; }

  this.getcartprodidlist=function() { return this.cartprod_idlist; }
  this.setcartprodidlist=function(pidlist) { this.cartprod_idlist=pidlist; }

  this.getcartprodskulist=function() { return this.cartprod_skulist; }
  this.setcartprodskulist=function(pskulist) { this.cartprod_skulist=pskulist; }
  
  this.getcartprodnamelist=function() { return this.cartprod_namelist; }
  this.setcartprodnamelist=function(pnamelist) { this.cartprod_skulist=pnamelist; }

  this.getcartpricelist=function() { return this.cartprod_pricelist; }
  this.setcartpricelist=function(ppricelist) { this.cartprod_pricelist=ppricelist; }

  this.getcartprodqtylist=function() { return this.cartprod_qtylist; }
  this.setcartprodqtylist=function(pqtylist) { this.cartprod_qtylist=pqtylist; }

  this.getcartprodsubtotallist=function() { return this.cartprod_subtotallist; }
  this.setcartprodsubtotallist=function(psubtotlist) { this.cartprod_subtotallist=psubtotlist; }
  
  this.listproperties=enumerateProperties;
}
var pcorderobj=new createpcorderobj; //create the shell object ready for population.
pcorderobj.appendeventto_finalizeorder("submitorder()");

//JavaScript Based Product Object for getting and setting Product based info for access at any time from JavaScript.
function createpcproductobj()
{
  this.productid=null;
  this.sku=null;
  this.name=null;
  this.qty=null;
  this.price=null;
  this.subtotal=null;

  //Setters and Getters
  this.getproductid=function() { return this.productid; }
  this.setproductid=function(pid) { this.productid=pid; }
  
  this.getsku=function() { return this.sku; }
  this.setsku=function(sku) { this.sku=sku; }
  
  this.getname=function() { return this.name; }
  this.setname=function(name) { this.name=name; }
  
  this.getqty=function() { return this.qty; }
  this.setqty=function(qty) { this.qty=qty; }
  
  this.getprice=function() { return this.price; }
  this.setprice=function(price) { this.price=price; }
  
  this.getsubtotal=function() { return this.subtotal; }
  this.setsubtotal=function(subtotal) { this.subtotal=subtotal; }

  this.listproperties=enumerateProperties;
}



function estimateshipping(formobj)
{
  document.getElementById('shipestresults').innerHTML='<p><center><b>Fetching Estimate...</b></center></p>';
  gethtml(formobj,'shipestresults');
  return false;
}


//Garry: Added function to pick from variety icons
function varietyiconpicker(clickobj,valuename)
{
   if (arguments.length  > 2 )
    {
      var fieldname = arguments[2]
      var fieldvalue = arguments[3]
      var doImage = false;
    }
   else
    {
      var thisidarray=clickobj.id.split("_");
      if(thisidarray.length != 3) { alert("Object named "+clickobj.id+".\nDoes not have three elements when an array."); return; }
      var fieldname=thisidarray[0]+"_"+thisidarray[1];
      var fieldvalue=thisidarray[2];
      var doImage = true;
    }
   
   var containerobjelements=document.getElementById(fieldname+"_container").getElementsByTagName("A");
   var textid=fieldname+"_text";
   var loopobj;
   var targetfield = document.getElementById(fieldname)
   targetfield.value=fieldvalue;
   if (targetfield.onchange) {targetfield.onchange()}
   if(typeof valuename=="string") { document.getElementById(textid).innerHTML=valuename; }
   // loop through all icon selectors for this variety Type ID and set the classname to "chosen" or "" accordingly.
   for (var i=0; i< containerobjelements.length; i++)
   {
      loopobj=containerobjelements[i];
      if(loopobj==clickobj) { loopobj.className="chosenvarietyicon"; }
      else { loopobj.className=""; }
   }
   if (doImage) {changeproddetailimage()};
}

function fetchpidDetail(mpid)
{
  if(window.MagicThumb)
  { 
    //MagicThumb.stop();
    MagicMagnify_stopMagnifiers(); 
  }
  var formobj=document.forms["productdetailform"];
  var myextraparams="";
  var myoutofstockaction="show";
  var domidtouse="productdetail";
  
  var selectorfields = fieldlist.split(",");
  for (var i= 0; i<selectorfields.length; i++)
      {
        getVariation(selectorfields[i],formobj)//get the value of each variation and put it into pagevariationidlist (which is actually an array)
      }
  var thisvariationidlist = pagevariationidlist.toString(); 
 
  if(window.pddetailurlstring) { myextraparams=window.pddetailurlstring; }
  if(window.jsoutofstockaction) { myoutofstockaction=window.jsoutofstockaction; }
  var newpidurl="/product_detail.cfm?includewrapper=0&mpid="+mpid+"&themedirpath="+jsthemedirpath+"&outofstockaction="+myoutofstockaction+"&rndid="+Math.random()+"&"+myextraparams;
  newpidurl+="&variationidlist="+thisvariationidlist+"&mode=checkproductexists";
      
  if(!parseInt(mpid)) { return; }
  try
  {
    //DEBUG STUFF:  window.open(newpidurl);
    //alert(newpidurl);
    submitFormData(newpidurl,poppidDetail)
    //gethtml(newpidurl,domidtouse,postAJAXCleanUp);//Run Post AJAX calls that might be needed. (for event handlers etc...)
    //mydomnode=document.getElementById(domidtouse);
  }
  catch(e) { window.location=newpidurl; }
}

function fetchPID()
  {
    if (isNaN(parseInt(this.pid))) return false;
    
    var formobj=document.forms["productdetailform"];
    var myextraparams = (window.pddetailurlstring) ? window.pddetailurlstring : "";
    var myoutofstockaction = (window.jsoutofstockaction) ? window.jsoutofstockaction : "show";
    var domidtouse="productdetail"; 
    
    var newpidurl="/product_detail.cfm?pid=" + this.pid + "&includewrapper=0&themedirpath=" + jsthemedirpath + "&outofstockaction=" + myoutofstockaction + "&rndid=" + Math.random() + "&" + myextraparams;
    submitFormData(newpidurl,poppidDetail)
    
    try {submitFormData(newpidurl,poppidDetail)}
    catch(e) { window.location=newpidurl; }
    return false
  }


function comparepidcheck(obj)
{
  var comparemode="Del";
  var prodidval=obj.value;
  if(obj.checked) { comparemode="Add"; }
  submitFormData("/includes/AJAX/set_comparepidlist_ajx.cfm?comparepid="+prodidval+"&comparemode="+comparemode,compareactionmsg(comparemode))
}

function compareactionmsg(txt)
{
  //Note: for now I am simply using two cookies rather than parsing out a multi string (NVP) cookie.
  var actiontxt="";
  var prodcomparecookie=null;
  txt=txt.toLowerCase();
  if(txt=="del")
  {
    actiontxt="You\'ve removed an item from your shopping comparison list.";
    if(readCookie("productCompareDEL")) { return; }
    else { createCookie('productCompareDEL',1,0) }
  }
  else
  {
     actiontxt="You have Added a new item to your Shopping Comparison list.";
     if(readCookie("productCompareADD")) { return; }
     else { createCookie('productCompareADD',1,0) }
  }
  alert(actiontxt+"\n\nThis message will not show again this session");
}

/*function poppidDetail(myintxt)
{
  var domidtouse="productdetail";
  var mydomnode=document.getElementById(domidtouse);
  mydomnode.innerHTML=myintxt;
  //window.pophtml(domidtouse,myintxt);
  window.postAJAXCleanUp(mydomnode);
}
*/

function poppidDetail(myintxt)
{
  var domidtouse="productdetail";
  var mydomnode=document.getElementById(domidtouse);
  mydomnode.innerHTML=myintxt;
  //window.pophtml(domidtouse,myintxt);
  function doCleanup()
    {
      window.postAJAXCleanUp(mydomnode);
    }
  setTimeout(doCleanup,200)
}


function changeproddetailimage()
{
   try
   {
      var detailimgobj=document.getElementById("proddetailimage");
      if(detailimgobj)
      {
         var imgsrc=detailimgobj.src
         imgsrc=imgsrc.replace(/\/\//g, "/"); //strip out any double slashes (a common mistake when appending an image to a path)
         var imgsrcfilearray=imgsrc.split("?")[0]; //make sure we only grab path info before any query string (to be safe)
         var imgsrcpatharray=imgsrcfilearray.split("/");
         var imgdirname=imgsrcpatharray[imgsrcpatharray.length-2];//the directory name for the image is the second to last
         var currentimage=imgsrcpatharray[imgsrcpatharray.length-1];
         //get the image name for this unique variety set/combination
         var newimgname=getvarietyimgname(imgdirname);
         if(newimgname=="" || newimgname.split(".").length < 2) { return; }
         if(newimgname.toLowerCase()==currentimage.toLowerCase()) { return; }
         imgsrcpatharray[imgsrcpatharray.length-1]=newimgname; //change the image name in the path to the new one
         imgsrcpatharray.splice(0,2)//remove the first two elements of the array as they are the HTTP and the Domain Name parts
         relativeimagepath="/"+imgsrcpatharray.join("/")//Now convert the array back to a string using forward slashes as the delimiter
         detailimgobj.src=relativeimagepath;
      }
   }
   catch(e) { return; }
}

//returns if value a should appear before value b (used for numerical array sorting
function numcompare(a,b)
{
   return a-b;
}


//trh:20061107:some optional parameters to urldelete as on admin side
function memberOnly(takeMeBack)
{
   var msg = "This is a member-only feature.\nWould you like to log in now?"
   if(confirm(msg)) { window.location= '/member_login.cfm' + ((takeMeBack)? '?takemeback=yes':''); }
   return false;
}
   
//determine if to use the onExit popup
var use_siteexitmessage = true; 

//Site Exit (onUnload Message)
function siteexitmessage(domain)
{
   if(use_siteexitmessage)
   {
      //alert(window.location.href)
      var exitwindow = newwindow('/siteexitmessage.cfm?domain='+domain,'siteexitmessage');
   }
 }

// ADD a bookmark function
//var storeurl=window.location.href
//var bookmarktitle="Gcommerce - The only way to sell"

function addbookmark(title,url)
{
   if (document.all) { window.external.AddFavorite(url, title); }
   else if (window.sidebar) { window.sidebar.addPanel(title, url, ""); }
}

//this function should be called from the header on ALL pages, and checks for the existance of the first available text field
//for all forms on the page. If an available form field exists, then it focuses and selects it, ready for user input.
//Garry Harstad:
function firstfocus()
{
   for(x=0;x<document.forms.length;x++)
   {
      var formobj=document.forms[x];
      for(i=0;i<formobj.length;i++)  
      {
         var elemobj=formobj.elements[i];
         if((elemobj.type=="text")&&(!elemobj.disabled))
         {
            //alert(formobj.name + '.' + elemobj.name + "SHOULD STOP HERE");
            try {
            elemobj.focus();
            return;
            }
            catch(e){return}
            //elemobj.select();
            
         }        
      }//end of form elements array loop
   }//end of forms array loop
}




  //common function: should be in admin and storefront sides.
  // used to figure out if the selection of a select box's text (not value) is "< new address >".
  //Because,if it is, we want to trigger the popup to create a new address
  function addnewaddresscheck(myobj,successoverride)
  {
     if(!myobj.options) { return false; }
     if(myobj.options[myobj.selectedIndex].text == "<New Address>")
     {
        var newaddress_value = myobj.options[myobj.selectedIndex].value;
        var sucessstring = '';
        
        if(!successoverride)
        {
           sucessstring = '&closeonsuccess=1'
        }
        var urlString = "if_address_edit.cfm?newname=1&setParentHeight=yes&orderitemdetailid="+newaddress_value + sucessstring;
        
        if (self.name == 'mywishlistsframe' )
          {
            
            urlString += '&fromwishlist=yes'
            parent.clearContent()
            var addressTab = parent.pdtablinks[2]
            addressTab.className = 'pdactive'
            addressTab.contentdiv.style.display = 'block'
            parent.myaddressesframe.location = urlString;
          }
        else
          {
            newwindow(urlString)
          }
        
       //set the selected option back to the first.
       //That way, if the user closes the window, they could select < New address > again
        myobj.selectedIndex = 0; 
     }
  }

//url is the relative OR absolute address of the page to be relocated to
function relocate(url)
{ window.location=url; }

//[obj] is the element (form object element) that called this function
//[val] is the value to place into the [mode] form variable before submitting it
function modeaction(obj,val,optionalformobj)
{ 
   if(obj || optionalformobj)
   {
     if(!optionalformobj)
     { var formobj=obj.form; }
     else
     { var formobj=optionalformobj; }
     if(formobj.mode)
     { formobj.mode.value=val; }
     formobj.submit();
   }
}

//[obj] is the element (form object element) that called this function
//[widget] is the TYPE of thing/widget that will be deleted
//NOTE: use urldelete(url,widget) function instead
function deleteaction(obj,widget)
{
   //var confmsg="Warning!\nYou are about to delete "+widget+".\nClick OK to continue the delete or\nclick CANCEL to abort the delete.";
   var confmsg="Are you sure you wish to delete "+widget+"?";
   var goahead=confirm(confmsg)
   if(goahead) { modeaction(obj,'delete'); }
}

function newwindow(url,version,name,width,height)
{
   var rnd = Math.random();
   if(!url)    { return false; }
   if(!version){ version = "standard"; }
   if(!width)  { width   = 720; }
   if(!height) { height  = 520; }
   if(!name)   { name    = "newwindow"; }
   var existingwindow = eval("window."+name);
   //if(!existingwindow)
   //{
     var size = "width="+width+",height="+height;
     switch(version)
     {
       case "standard":
         var properties=size+",toolbar=1,resizable=yes,scrollbars=yes";
       break;
       case "stripped":
         var properties=size+",toolbar=0,location=0,directories=0,status=1,menubar=0,resizable=yes";
       break;
       case "nolocation":
         var properties=size+",location=0";
       break;
       case "scrolling":
         var properties=size+",toolbar=0,location=0,scrollbars=yes";
       break;
       default:  properties=size+",toolbar=1,scrollbars=yes";
     }
     var rndseed = ""+Math.random();
	  //existingwindow = window.open(url+"&popup=1",name,properties);
     existingwindow = window.open(url+"&rnd="+rndseed,name,properties);
     if (typeof existingwindow != undefined) { existingwindow.focus(); }
}

  //-----------------------------------------------------------------------
  // loop over fieldname strings to get the form-field types and values
  // of the [fromprefix] fields and copy the values/select/check the
  // corresponding [toprefix] form-fields.
  // Garry Harstad November 2002
  // Garry Harstad January 2003: from_prefix is no longer required.
  // mod 1/27/2003 toh - added optional exception list
  //-----------------------------------------------------------------------
   function copyfields(clickedobj,fromprefix,toprefix,exceptionList)
   {
     if((!clickedobj) || (!toprefix)) { return false; }
     var formobj = clickedobj.form;
     if (exceptionList) 
     { var exceptionArray=exceptionList.split(","); }
     //alert(formobj.name);
     for(i=0;i<formobj.elements.length;i++)
     {
       var elementobj  = formobj.elements[i];
       var elementname = elementobj.name;
       if (elementname && (elementname.substring(0,fromprefix.length) == fromprefix) )
       {
         var thissuffix = elementname.substring(fromprefix.length,elementname.length)
         
         //mod 1/27/2003 ........................................
         var thisExcepted = false; //reset the exception flag
         if (exceptionArray) //if the exceptionArray object was created from the passed exceptionList
         {
           for (x=0; x<exceptionArray.length; x++) //loop through the array of exceptions
           {
              if (thissuffix==exceptionArray[x])  //if the name matches an exception flag the thisExcepted flag for exclusion
              {
                thisExcepted = true;
                break;
              }	                      
           }
         }//end of exception check
         //.............................................
         var tofield = formobj.elements[toprefix+thissuffix];
         if(tofield && !thisExcepted) { copyfield(elementobj,tofield); }
       }
     }
   }
   
   //url is the relative OR absolute address of the page to be relocated to should include query string parameters if required
   function urldelete(url,type,name,extratext)
   {
      //trh:20061107:add optional parameters to urldelete
      // var confmsg="Warning!\nYou are about to delete.\nClick OK to continue the delete or click CANCEL to abort the delete.";
      var confmsg = "WARNING!\nYou are about to delete";
      if (type == null && name == null) { confmsg += " this item"; }
      else if (type != null && name == null) { confmsg += " this " + type;}
      else if (type == null && name != null) { confmsg += " \"" + name + "\""; }
      else { confmsg += " the " + type + " called " + "\""  + name + "\"";}
      if(extratext) {confmsg += extratext}
      confmsg += ".\nClick OK to continue the delete or click CANCEL to abort the delete.";
      
      var goahead=confirm(confmsg)
      if(goahead) { window.location=url; }
   }
   
   //Garry Harstad
   //This function copies/selects the contents/values of one form object field to another
   //The function requires the "from" object form element and the "to" object form element.
   //the function will determine the field type and value(s) and perform the appropriate action(s).
   function copyfield(fromobj,toobj)
   {  //alert("toobj=["+toobj+"]\rfromobj=["+fromobj+"]")
      //G.Harstad: added generic flag to allow the changing of the form element "toobj".
      //if this 'checkbox' field exists in the "toobj"'s form it will check the value and if CHECKED it will allow the copy otherwise ignore this copy request/function call
      if((!toobj.form.allowfieldcopy) || (!toobj.form.allowfieldcopy.checked)) { return; }
      if((!fromobj) || (!toobj)) { return; alert("You must pass valid ''to'' and ''from'' objects to the ''copyfield'' function\rYour passed values were\rTOOBJ = ["+toobj+"]\rFROMOBJ = ["+fromobj+"]"); return; }
      else
      {
         var tofieldtype = toobj.type.toLowerCase();
         switch (tofieldtype)
   		{
        case "text"            : toobj.value = fromobj.value; break;
        case "textarea"        : toobj.value = fromobj.value; break;
        case "password"        : toobj.value = fromobj.value; break;
        case "file"            : toobj.value = fromobj.value; break;
        case "checkbox"        : toobj.checked = fromobj.checked; break;
        case "radio"           : toobj.checked = fromobj.checked; break;
        case "select-one"      : toobj.selectedIndex = fromobj.selectedIndex; break;
            //G.Harstad: Note the multiple select will need to become looped because of possible multiple selections from the [elementobj]. ("multiple-select" form-fields permit multiple selections [selectedIndex'es'].)
   			case "select-multiple" :
               //alert("toobj name=["+toobj.name+"]\rfromobj name=["+fromobj.name+"]")
               if(fromobj.options.length)
               {
                  for (var i=0; i<fromobj.options.length; i++)
                  { toobj.options[i].selected = fromobj.options[i].selected; }
               }
              default                : toobj; //default case does nothing but read the form [toobj] object as true.
   		} //end switch
         return true;// All done simply return true to continue
      }
   }
   
//----------------------------------------------------------------------------
//togglelayer shows or hides an object based on the display property (not visibility)
//it will detect the kind element it is and therefore the cross-browser method of hiding or showing the object.
//----------------------------------------------------------------------------
function togglelayer(divid,override)
{
   var myobj = document.getElementById(divid);
   if(!myobj) { window.status="[fn togglelayer] Problem! Could find element with ID '"+divid+"' to toggle."; return; }
   var mytagname = myobj.tagName
   //get the proper display style value, depending on element and browser
   //use self.innerHeight, which IE doesn't support, to determine block or table style
   switch (mytagname)
   {
      case 'DIV': { var  showstyle = "block"; break; }
      case 'SPAN': { var  showstyle = "inline"; break; }
      case 'I': { var  showstyle = "inline"; break; }
      case 'P': { var  showstyle = "block"; break; }
      case 'TABLE': { var  showstyle = self.innerHeight ? "table" : "block"; break; }
      case 'TR': { var  showstyle = self.innerHeight ? "table-row" : "block"; break; }
      case 'TD': { var  showstyle = self.innerHeight ? "table-cell" : "block"; break; }
      case 'TBODY': { var  showstyle = self.innerHeight ? "table-row-group" : "block"; break; }
      default: { var  showstyle = ""; break; }
   }
   if(override == 1) { myobj.style.display = showstyle; return;}
   if(override == 0) { myobj.style.display = "none"; return;}
   if ((myobj.style.display == showstyle)||(myobj.style.display=="")||(myobj.style.display==null)) { myobj.style.display = "none"; }
   else { myobj.style.display = showstyle; }
}

//the optional override parameter forces the div to be displayed or hidden accordingly (1=display. 0-hide)
function togglelayervis(divid,override)
{
   var myobj = document.getElementById(divid);
   if (myobj == null) {alert(divid); return false}
   if(override == 1) { myobj.style.visibility = "visible"; return; }
   if(override == 0) { myobj.style.visibility = "hidden"; return; }
   if (myobj.style.visibility=="visible") { myobj.style.visibility = "hidden"; }
   else { myobj.style.visibility = "visible"; }
}

function preselect(formobj,selectname,matchtype,matchvalue)
{
   if(!formobj || !selectname) { return; }
   var selectobj = formobj.elements[selectname];
   if(!matchtype) {  matchtype="option"; }
   if(!matchvalue || !selectobj.options.length) { selectobj.selectedIndex=0; return; }
   
   for(i=0; i<selectobj.options.length; i++)
   {
      if(matchtype == "option")
      { thisval  = selectobj.options[i].value; }
      else
      { thisval  = selectobj.options[i].text; }
      if(matchvalue == thisval) { selectobj.selectedIndex = i; return; }
   }
}


//Product sorting function
function psort(sortcode,formname)
{
	if(typeof formname == "undefined") { formname="prodsortform"; }
	var formobj=document.forms[formname];
	if(!formobj) { alert("[fn psort] No form named '"+formname+"'"); return; }	
	if(typeof sortcode != "undefined" && sortcode != "") { formobj.productsortcode.value=sortcode; }
	formobj.submit();
}

//Adds a new class to an object, preserving existing classes
function addClass(obj,cName){ killClass(obj,cName); return obj && (obj.className+=(obj.className.length>0?' ':'')+cName); }

//Removes a particular class from an object, preserving other existing classes.
function killClass(obj,cName){ return obj && (obj.className=obj.className.replace(new RegExp("^"+cName+"\\b\\s*|\\s*\\b"+cName+"\\b",'g'),'')); }

//Returns true if the object has the class assigned, false otherwise.
function hasClass(obj,cName){ return (!obj || !obj.className)?false:(new RegExp("\\b"+cName+"\\b")).test(obj.className) }


//----------------------------------------------------------------------------
// Returns both x and y position of an object
//----------------------------------------------------------------------------
function getObjPosition(objRef)
  {
    var position = {x:0, y:0}
    if(objRef.offsetParent)
      {
        while (objRef.offsetParent)
          {
            position.x += objRef.offsetLeft;
            position.y += objRef.offsetTop;
            objRef = objRef.offsetParent
          }       
      }//offsetParent exists
     else 
      {
       if (objRef.x) { position.x += objRef.x; }
       if (objRef.y) { position.x += objRef.y; }
      }
    return position;
  }


function toggleFieldset(divid,thisbutton)
{
 togglelayer(divid);
 if (thisbutton.value == '\>')
   {
	thisbutton.value = 'v'
   }
 else thisbutton.value = '\>'
} 
  
/*function doPagination(startrow,formname,startelem)
   { 
      var formobj = document.forms[formname]
      formobj.elements[startelem].value=startrow;
      formobj.submit();
   }*/
   
   
function getNodeText(obj)
  {
    if (obj.nodeType == 3)  {return(obj.nodeValue)}//obj is a text node, return its value    
    if(obj.firstChild == null) {return null;} //obj doesn't have children, return null    
    return getNodeText(obj.firstChild) //obj's an element, call myself. 
  }
  
/*function to make an XMLHttpRequest. Must supply a URL (with variables, if necessary,
  and a reference to a function to handle the response.*/
function makeRequest(url,fnReference) {

    http_request = false;

    if (window.XMLHttpRequest) { // Mozilla, Safari,...
        http_request = new XMLHttpRequest();           
    } else if (window.ActiveXObject) { // IE
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
        }
    }

    if (!http_request) {
        alert('Giving up :( Cannot create an XMLHTTP instance');
        return false;
    }
    http_request.onreadystatechange = fnReference;        
    http_request.open('GET', url, true);
    http_request.send(null);
}

//get the mouse position

function getmousepos(e)
{
  var ie = (document.all) ?true: false //modified to get around 'undectable' document.all support
  var usesDOM = document.getElementById && !document.all
  var position = {x:0,y:0}  

  position.x = (usesDOM)? e.pageX : event.x+ietruebody().scrollLeft;
  position.y =(usesDOM)? e.pageY : event.y+ietruebody().scrollTop;
  return position
  
}

function ietruebody() { return (!(document.compatMode && document.compatMode!="BackCompat"))? document.documentElement : document.body }

//"A Good Enough addEvent"  by Austin Matzko
function addEventProperty( obj, type, fn ) {
    if (obj.addEventListener)
            obj.addEventListener(type, fn, false);
    else if (obj.attachEvent)
            obj.attachEvent('on' + type, function() { return fn.apply(obj, new Array(window.event));});
}

//returns an object papering over differences in event objects
function commonEventProperties(evtObj)
  {
    var returnObj = new Object()
    returnObj.targetObj = (evtObj.target) ? evtObj.target : evtObj.srcElement
    //add more as needed.
    return returnObj
  }


//===================== JS Core Extensions ==============================================
function enumerateProperties()
{
  var pString = this + '\n\nProperties:\n---------------\n';
  for (property in this)
    {
      if (typeof this[property] == 'function') 
        {
          {pString += property + ': (function)\n';}
        }
      else
      
        {pString += property + ': ' + this[property] + '\t\t\tType: ' + typeof this[property] + '\n';}
    }
  return pString
}
/*Object.prototype.toFullString = enumerateProperties*/


function postAJAXCleanUp(DOMnode)
  {
    if (!document.getElementById) {return}
    if (DOMnode == null) {DOMnode = document}
    if (window.initializeVarieties && typeof(window.initializeVarieties) == 'function') {initializeVarieties()}
    addAdd2CartHandlers(DOMnode)
    if (window.hasPDtabs) {initializeTabs(DOMnode)}
    if (window.postAJAXfn  && typeof(window.postAJAXfn) == 'function'){window.postAJAXfn()}
    
    //module driven Flash Zoom Script (on ajax load, it mneeds to re run the main script to run the zoom/magnify handlers again)
    if(window.MagicMagnify_findMagnifiers)
    {
      MagicMagnify_findMagnifiers();
    }
    /*
    if(window.MagicThumb)
    { 
      MagicThumb.start();
    }
    */
  }
  
 function clearAll(formname,exceptionList) 
	    {
	     var thisForm = document.forms[formname] //get the form element
       
	     //create an array of exceptions--fields NOT to be be reset
	     if (exceptionList)
	        {
	         var exceptionArray=exceptionList.split( ",")
	        }
	      else exceptionArray= new Array()
	     //set up loop to loop through all form elements
       for(i=0;i<thisForm.length;i++)  
	         {
	          thisElem=thisForm.elements[i] //put current element in variable
	          //begin checking to see if this element is on the exception list
	          var thisExcepted = false;
	          if (exceptionArray.length != 0) //if we have a list of exceptions 
	             {
	              for (x=0; x<exceptionArray.length; x++) //loop through the list of exceptions
	                 {
	                  if (thisElem.name==exceptionArray[x])  //if the name matches an exception
	                      {
	                       thisExcepted= true;
	                       break
	                      }	                      
	                 }
	             }
	             
								//do the actual clearing, if this element has not been excepted
								if (!thisExcepted)  
									{ 									  
										switch (thisElem.type)  //depending on type, do various things
												{
												 case "text"            : thisElem.value = ""; break;
												 case "password"        : thisElem.value = ""; break;
												 case "file"            : thisElem.value = ""; break;
												 case "textarea"        : thisElem.value = ""; break;
												 case "checkbox"        : thisElem.checked = false; break;
												 case "radio"           : thisElem.checked = false; break;
												 case "select-one"      : thisElem.selectedIndex=0; break;
												 case "select-multiple" : 
															for (j=0; j<thisElem.options.length;j++)
																{
																 thisElem.options[j].selected=false
																}												 
												}  //end switch										
									 }//end if
	          }//end for
	    } //end function

      
//----------------- Basic JavaScript Cookie handling functions -----------------
function createCookie(name,value,days)
{
	if (days)
  {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++)
  {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) { createCookie(name,"",-1); }
//----------------- /Basic JavaScript Cookie handling functions -----------------
      

//------------- COMMUNITY WEB X.0 SCRIPTS -------------
  
  //Facebook Link Share Script
  function fbs_click(u,t)
  {
    if(typeof u=="undefined") { var u=location.href; }
    if(typeof t=="undefined") { var t=document.title; }
    window.open("http://www.facebook.com/sharer.php?u="+encodeURIComponent(u)+"&t="+encodeURIComponent(t),"sharer","toolbar=0,status=0,width=626,height=436");
    return false;
  }
   
//------------- /COMMUNITY WEB X.0 SCRIPTS -------------