
// ------------ Pageflex AJAX code

function newHttpRequest()
{
  if (window.XMLHttpRequest)
    return new XMLHttpRequest();
  if (window.ActiveXObject)
    return new ActiveXObject("Microsoft.XMLHTTP");
  return null;
}

var PFSF_xmlRequest;
var PFSF_AjaxUrl;
var PFSF_AjaxMessagePrefixes = new Array();
var PFSF_AjaxMessages = new Array();
var PFSF_AjaxSkip = false;
var PFSF_changeStamp = 1;
var PFSF_lastReplyStamp = 0;
var PFSF_dynamicUpdateLevel = 0;

function PFSF_AjaxUpdateForm(urlExtra, forceSynchronous)
{
  if (PFSF_AjaxUrl == "" || PFSF_AjaxUrl == undefined || PFSF_AjaxSkip)
    return false; // didn't submit

  if (typeof StorefrontPreAjaxHook != typeof StorefrontPreAjaxHook_283981501AD46548)
     StorefrontPreAjaxHook();

  if (PFSF_xmlRequest != null)
     PFSF_xmlRequest.abort();

  if (urlExtra == undefined)
    urlExtra = "";

  //alert("Updating " + urlExtra);

  if (urlExtra.substr(0, 5) == "quick")
  {
    // don't wait for preview
  }
  else
  {
    var pleaseWait = PFSF_Find("txtPleaseWait");
    
    if (pleaseWait == undefined || pleaseWait == null)
        pleaseWait = PFSF_Find("StepArea_txtPleaseWait");
      
    if (pleaseWait != undefined && pleaseWait != null)
    {
      //alert("Changing graphic");
      pleaseWait.innerHTML = "<span class='previewWaitMessage'><img src='Images/AjaxWait.gif' alt='' height='18' width='18' style='vertical-align: middle;'>&nbsp;" + PFSF_String_PleaseWait + "</span>";
    }
  }

  var req = newHttpRequest();
  PFSF_xmlRequest = req;
  req.open("POST", PFSF_AjaxUrl, !forceSynchronous);
  if (!forceSynchronous)
    req.onreadystatechange = PFSF_CallHandleAjaxResponse; 
  req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;");
  // alert("Sending request");
  req.send(urlExtra + PFSF_ConstructAjaxQuery() + "&changeStamp=" + PFSF_changeStamp);
  if (forceSynchronous)
    PFSF_HandleAjaxResponse(true);
  return true;
}

function PFSF_CallHandleAjaxResponse(evt)
{
    PFSF_HandleAjaxResponse(false);  // in Safari, evt is non-null
}

function PFSF_HandleAjaxResponse(forceSynchronous)
{
  if (forceSynchronous || 
      (PFSF_xmlRequest != null && PFSF_xmlRequest.readyState == 4))
  {
      var pageNumberDisplay = PFSF_Find("txtPleaseWait");
    
      if (pageNumberDisplay == undefined || pageNumberDisplay == null)
         pageNumberDisplay = PFSF_Find("StepArea_txtPleaseWait");

      if (pageNumberDisplay != undefined && pageNumberDisplay != null)
        pageNumberDisplay.innerHTML = "";
      if (PFSF_GetResponseStatusCode(PFSF_xmlRequest) == 200)
        PFSF_ParseAjaxResponse(PFSF_xmlRequest);
      PFSF_xmlRequest = null;
  }
}

// workaround for NS_ERROR_NOT_AVAILABLE (Mozilla bug)
function PFSF_GetResponseStatusCode(xmlHttpRequest)
{
  var status;
  try {
    status = xmlHttpRequest.status;
  }
  catch(e) { 
    status = 0; // no access to status right now
  }
  return status;
}

function PFSF_HtmlEscape(s)
{
  return s.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;");
}

function PFSF_escape(s)
{
  if (s == undefined)
    return "";
  s = escape(s);
  // escape doesn't handle + correctly, so we'll patch
  s = s.replace(/\+/g, "%2B");
  // escape doesn't handle UTF-8 correctly, so we'll patch
  s = s.replace(/\%8/g, "%*2%8");
  s = s.replace(/\%9/g, "%*2%9");
  s = s.replace(/\%A/g, "%*2%A");
  s = s.replace(/\%B/g, "%*2%B");  
  s = s.replace(/\%C/g, "%*3%8");
  s = s.replace(/\%D/g, "%*3%9");
  s = s.replace(/\%E/g, "%*3%A");
  s = s.replace(/\%F/g, "%*3%B");
  s = s.replace(/\%\*/g, "%C");
  return s;
}

function PFSF_GetTextContent(n)
{
  if (n.text != null)
    return n.text;
  if (n.textContent != null)
    return n.textContent;
  if (n.nodeValue != null)
    return n.nodeValue;
  if (n.firstChild != null)
    return n.firstChild.nodeValue;
  return null;
}


// ------------ Pageflex FFF code

var FieldIDs = new Object();
var PFFormMode = '';

var PFSF_FindCache = new Array();
var PFSF_LastNodeWalked = null;
var PFSF_WalkStamp = 0;

function PFSF_WalkNext(n)
{
   if (n.firstChild != null)
       return n.firstChild;
   while (n != null)
   {
      if (n.nextSibling != null)
          return n.nextSibling;
       n = n.parentNode;
   }
   return null;
}

function PFSF_Walk()
{
   if (PFSF_LastNodeWalked == null)
   {
       PFSF_LastNodeWalked = document;
       PFSF_WalkStamp++;
   }
   var n = PFSF_LastNodeWalked;
   while (n != null)
   {
      if (typeof n != 'function' && n["PFSF_Stamp"] == PFSF_WalkStamp)
      {
        // Walking in circles
        n = null;
        break;
      } else if (typeof n == 'function') // skip applet
        n = PFSF_WalkNext(n);

      if (n.sourceIndex != undefined)
          n["PFSF_Stamp"] = PFSF_WalkStamp;

      PFSF_LastNodeWalked = n;
      var id = n.id;
      if ((n.type == "hidden" ||
           n.type == "radio") && 
          n.name != null &&
          n.name != "")
          id = n.name;
      if (id != null && id != "")
      {
         var c = PFSF_FindCache[id];
         if (c == null)
            c = new Array();
         c.push(n);
         PFSF_FindCache[id] = c;
      }
      var nn = n;
      n = PFSF_WalkNext(n);
      if (nn == n)
        break; // found mismatched html tags, we're not making any more forward progress
   }
}

// the equivalent of IE's document.all but will work in all browsers
function PFSF_Find(fid)
{
   if (document.all != undefined && document.all.item != undefined)
      return document.all.item(fid);

   PFSF_Walk();
   var c = PFSF_FindCache[fid];
   if (c == null || c.length == 0)
     return null;
   if (c.length == 1)
     return c[0];
   return c;
}

function PFSF_GetFieldElementByName(fieldName)
{
    return PFSF_Find("FIELD_" + FieldIDs[fieldName]);
}

function PFSF_SetControlValue(control, v)
{
  if (control == null)
    return false;

  var changed = false;
  var t = control.type;

  // One way for selects....
  if (t == "select-one" || t == "select-multiple")
  {
    var o = control.options;
    var i;
    for (i=0; i<o.length; i++)
    {
        var selectThisOne = 
           (("\n" + v + "\n").toLowerCase().
            indexOf("\n" + o[i].value.toLowerCase() + "\n") != -1);
        if (o[i].selected != selectThisOne)
           changed = true;
        o[i].selected = selectThisOne;
    }
  }
  else if (t == "radio")
  {
      var checkThisOne = (v == control.value);
      if (control.checked != checkThisOne)
          changed = true;
      control.checked = checkThisOne;
  }
  // ... one way for radios ...
  else if (t == null && control.length > 0)
  {
    var i;
    if (control[0].type == "radio")
    {
        t = "radio";
        for (i=0; i<control.length; i++)
        {
           var checkThisOne = (v == control[i].value);
           if (control[i].checked != checkThisOne)
              changed = true;
           control[i].checked = checkThisOne;
        }
    }
    else
    {
       // hey, that's not a radio control.
       // it's another kind of control that has
       // mutiple instances with the same name!
       // so we'll concatenate all of those values...
       for (i=0; i<control.length; i++)
       {
           if (PFSF_SetControlValue(control[i], v))
              changed = true;
       }
    }
  }
  // ... one way for checkboxes ...
  else if (t == "checkbox")
  {
     var checkThisOne = (v == control.value);
     if (checkThisOne != control.checked)
        changed = true;
     control.checked = checkThisOne;     
  }
  // ... and one way for text, hidden, and password
  else 
  {
     if (control.value != v)
        changed = true;
     control.value = v;
  }
  
  if (v == "" && control.getAttribute != undefined && control.getAttribute("pfsf_relatedid") != undefined)
  {
    PFSF_SetControlValue(PFSF_Find(control.getAttribute("pfsf_relatedid")), "");
  }

  return changed;
}

function PFSF_GetControlValue(control, forXML)
{
  if (control == null)
    return null;

  var v = "";
  var t = control.type;

  // One way for selects....
  if (t == "select-one" || t == "select-multiple")
  {
    var o = control.options;
    var i;
    for (i=0; i<o.length; i++)
    {
     if (o[i].selected)
     {
      if (v != "") v += "\n"
      v += o[i].value;
     }
    }
  }
  // ... one way for radios ...
  else if (t == "radio")
  {
      if (control.checked)
      {
         var controlOrAncestor = control;
         while (controlOrAncestor != null && 
                (controlOrAncestor.style == null ||
                 controlOrAncestor.style.display == null ||
                 controlOrAncestor.style.display == ""))
         {
             controlOrAncestor = controlOrAncestor.parentNode;
         }
         if (controlOrAncestor != null &&
             controlOrAncestor.style != null &&
             controlOrAncestor.style.display == "none")
         {
             // since radio buttons can't be "cleared",
             // if it's hidden and its "when hidden" behavior
             // is "clear" then pretend it has no value
             var i;
             for (i = 0; i < PFSF_conditionalFields.length; i++)
                 if (PFSF_conditionalFields[i].antecedantFieldName == control.name)
                 {
                     if (PFSF_conditionalFields[i].whatToDoWhenHidden == "C")
                         return "";
                     break;
                 }
         }
         v = control.value;
      }
  }
  else if (t == null && control.length > 0)
  {
    var i;
    if (control[0].type == "radio")
    {
        t = "radio";
        for (i=0; i<control.length; i++)
           if (control[i].checked)
              v = control[i].value;
    }
    else
    {
       // hey, that's not a radio control.
       // it's another kind of control that has
       // mutiple instances with the same name!
       // so we'll concatenate all of those values...
       for (i=0; i<control.length; i++)
       {
           var voic = PFSF_GetControlValue(control[i], forXML);
           if (voic == null)
               continue;
           if (v != "" && voic != "") v += "\n"
           v += voic;
       }
    }
  }
  // ... one way for checkboxes ...
  else if (t == "checkbox")
  {
     v = (control.checked? 
          (control.value != "" &&
           control.value != null ?
           control.value : "checked")
         :
          (forXML || control.unvalue != null ?
           control.unvalue : ""));
  }
  // ... and one way for text, hidden, and password
  else 
     v = control.value;

  return v;
}

function PFSF_GetControlValueLabel(control, forXML)
{
  if (control == null)
    return null;

  var v = "";
  var t = control.type;

  // One way for selects....
  if (t == "select-one" || t == "select-multiple")
  {
    var o = control.options;
    var i;
    for (i=0; i<o.length; i++)
    {
     if (o[i].selected)
     {
      if (v != "") v += "\n"
      v += o[i].text;
     }
    }
  }
  // ... one way for radios ...
  else if (t == "radio")
  {
      if (control.checked)
      {
         var controlOrAncestor = control;
         while (controlOrAncestor != null && 
                (controlOrAncestor.style == null ||
                 controlOrAncestor.style.display == null ||
                 controlOrAncestor.style.display == ""))
         {
             controlOrAncestor = controlOrAncestor.parentNode;
         }
         if (controlOrAncestor != null &&
             controlOrAncestor.style != null &&
             controlOrAncestor.style.display == "none")
         {
             // since radio buttons can't be "cleared",
             // if it's hidden and its "when hidden" behavior
             // is "clear" then pretend it has no value
             var i;
             for (i = 0; i < PFSF_conditionalFields.length; i++)
                 if (PFSF_conditionalFields[i].antecedantFieldName == control.name)
                 {
                     if (PFSF_conditionalFields[i].whatToDoWhenHidden == "C")
                         return "";
                     break;
                 }
         }
         v = control.value;
      }
  }
  else if (t == null && control.length > 0)
  {
    var i;
    if (control[0].type == "radio")
    {
        t = "radio";
        for (i=0; i<control.length; i++)
           if (control[i].checked)
              v = control[i].value;
    }
    else
    {
       // hey, that's not a radio control.
       // it's another kind of control that has
       // mutiple instances with the same name!
       // so we'll concatenate all of those values...
       for (i=0; i<control.length; i++)
       {
           var voic = PFSF_GetControlValueLabel(control[i], forXML);
           if (voic == null)
               continue;
           if (v != "" && voic != "") v += "\n"
           v += voic;
       }
    }
  }
  // ... one way for checkboxes ...
  else if (t == "checkbox")
  {
     v = (control.checked? 
          (control.value != "" &&
           control.value != null ?
           control.value : "checked")
         :
          (forXML || control.unvalue != null ?
           control.unvalue : ""));
  }
  // ... and one way for text, hidden, and password
  else 
     v = control.value;

  return v;
}

function PFSF_GetFieldValueByName(fieldName, forXML)
{
    var f =  PFSF_Find(fieldName);

    if (f == null ||
        f.selectedIndex < 0)
        return "";

    var s = null;
    if (PFFormMode == 'VIEW')
        s = f.value;
    else
        s = PFSF_GetControlValue(f, forXML);

    return s;
}

function PFSF_GetFieldValueLabelByName(fieldName, forXML)
{
    var f =  PFSF_Find(fieldName);

    if (f == null ||
        f.selectedIndex < 0)
        return "";

    var s = null;
    if (PFFormMode == 'VIEW')
        s = f.value;
    else
        s = PFSF_GetControlValueLabel(f, forXML);

    return s;
}

function PFSF_SetupAntecedantField(f)
{
    if (f == null)
        return;

    if (f.type == null &&
        f.length > 0) // it's an array of controls
    {
        var i;
        for (i=0; i<f.length; i++)
           PFSF_SetupAntecedantField(f[i]);
    }
    else if (f.type == "text" ||
             f.type == "textarea" ||
             f.type == "password")
    {
        f.onchange = 
            new Function("e", "PFSF_ShowHideConditionalFields(2, this);");
    }
    else if (f.type == "select-one" ||
             f.type == "select-multiple")
    {
        f.onchange = 
            new Function("e", "PFSF_ShowHideConditionalFields(1, this);");
    }
    else if (f.type == "checkbox" ||
             f.type == "radio")
    {
        f.onclick = 
            new Function("e", "PFSF_ShowHideConditionalFields(2, this);");
    }
}

function PFSF_ShowElement(showIt, elt)
{
   if (elt == null || elt.style == null)
     return;
   if (!showIt)
   {
      elt.style.display = "none";
      return;
   }
   var bIsIE = (navigator.appName.indexOf("Microsoft") > -1); 
   if (elt.tagName == "INPUT")
   {
      elt.style.display = "inline";
      return;
   } 
   else if (!bIsIE && (elt.tagName == "TR" || elt.tagName == "TD"))
   {
      // non-IE uses table-row/table-cell instead of block
      elt.style.display = (elt.tagName == "TR") ? "table-row" : "table-cell";
      return;
   }
   elt.style.display = "block";
   return;
}

function PFSF_ShowField(showIt, fieldName, defaultValue, whatToDoWhenHidden)
{
    var fid = FieldIDs[fieldName];
    var theField = PFSF_Find("FIELD_" + fid);
    var valueWasChanged = false;
    if (theField != null)
    {
        var oneElement = theField;
        if (theField.length > 0)
           oneElement = theField[0];

        if (oneElement.style == null || 
            oneElement.style.display == null ||
            oneElement.style.display == "none") // was hidden
        {
          var fidName = "FIELD_" + FieldIDs[fieldName];
          if (showIt && // transitioning to visible
              whatToDoWhenHidden != 'K') // and wasn't "keep"
          {
             if (PFSF_GetFieldValueByName(fidName, false) == "")
                valueWasChanged = PFSF_SetControlValue(theField, defaultValue);
          }
        }
        else // was visible
        {
          if (!showIt) // transitioning to hidden
          {
            if (whatToDoWhenHidden == 'R') // reset to default
            {
              PFSF_SetControlValue(PFSF_Find("FIELD_" + fid + "_IMGNAME"), '');
              valueWasChanged = PFSF_SetControlValue(theField, defaultValue);
            }
            else if (whatToDoWhenHidden == 'C') // clear it
            {
              valueWasChanged = PFSF_SetControlValue(theField, '');
              PFSF_SetControlValue(PFSF_Find("FIELD_" + fid + "_IMGNAME"), '');
            }
          }
        }
    }

    PFSF_ShowElement(showIt, PFSF_Find("LABEL_" + fid));
    PFSF_ShowElement(showIt, PFSF_Find("FIELD_" + fid));
    PFSF_ShowElement(showIt, PFSF_Find("VALUE_" + fid));
    PFSF_ShowElement(showIt, PFSF_Find("ROW_" + fid));
    PFSF_ShowElement(showIt, PFSF_Find("DIV_" + fid));
    return valueWasChanged;
}

function PFSF_ShowHideOneConditionalField(
        antecedantFieldName,
        comparisonOperator,
        comparisonValue,
        consequentFieldName,
        defaultValue,
        whatToDoWhenHidden)
{
    var antecedantValue = PFSF_GetFieldValueByName(antecedantFieldName, false);
    if (antecedantValue == null)
        antecedantValue = "";
    if (comparisonValue == null)
        comparisonValue = "";
    var showIt = true;
    switch (comparisonOperator)
    {
        case '!':
            showIt = false;
            break;

        case 'eq': 
            showIt = (antecedantValue.toLowerCase() == 
                      comparisonValue.toLowerCase()); 
            break;

        case 'bw': 
            showIt = (antecedantValue.toLowerCase().
                        substr(0, comparisonValue.length) ==
                      comparisonValue.toLowerCase()); 
            break;

        case 'ew': 
            showIt = (antecedantValue.toLowerCase().
                        substr(antecedantValue.length-comparisonValue.length) ==
                      comparisonValue.toLowerCase()); 
            break;

        case 'cn': 
            showIt = (antecedantValue.toLowerCase().indexOf(
                      comparisonValue.toLowerCase()) != -1); 
            break;

        case 'sl':  // selected (for multi-valued)
            showIt = (("\n" + antecedantValue.toLowerCase() + "\n").indexOf(
                      ("\n" + comparisonValue.toLowerCase() + "\n")) != -1); 
            break;

        case 'vl': // is valid (against the regex)
        case 're': 
            showIt = antecedantValue.match(new RegExp(comparisonValue, "")) != null;
            break;

        case '!eq': 
            showIt = !(antecedantValue.toLowerCase() == 
                      comparisonValue.toLowerCase()); 
            break;

        case '!bw': 
            showIt = !(antecedantValue.toLowerCase().
                        substr(0, comparisonValue.length) ==
                      comparisonValue.toLowerCase()); 
            break;

        case '!ew': 
            showIt = !(antecedantValue.toLowerCase().
                        substr(antecedantValue.length-comparisonValue.length) ==
                      comparisonValue.toLowerCase()); 
            break;

        case '!cn': 
            showIt = !(antecedantValue.toLowerCase().indexOf(
                      comparisonValue.toLowerCase()) != -1); 
            break;

        case '!sl':  // selected (for multi-valued)
            showIt = !(("\n" + antecedantValue.toLowerCase() + "\n").indexOf(
                       ("\n" + comparisonValue.toLowerCase() + "\n")) != -1); 
            break;

        case '!vl': // is valid (against the regex)
        case '!re': 
            showIt = !(antecedantValue.match(new RegExp(comparisonValue, "")) != null);
            break;
    }

    if (false) // for debugging
      alert("AFN=" + antecedantFieldName + "\n" +
            "AFV=" + antecedantValue + "\n" +
            "COP=" + comparisonOperator + "\n" +
            "CMV=" + comparisonValue + "\n" +
            "SIT=" + showIt + "\n" +
            "CFN=" + consequentFieldName);

    return PFSF_ShowField(showIt, consequentFieldName, defaultValue, whatToDoWhenHidden);
}
 
function PFSF_ShowHideConditionalFields(dynamicUpdateLevel, originatingObject)
{
    if (typeof StorefrontEvaluateFieldsHook !=
        typeof StorefrontUndefined_283981501AD46548)
        StorefrontEvaluateFieldsHook(originatingObject);

    var restartCount = 0;
    var i;
    for (i = 0; i < PFSF_conditionalFields.length; i++)
        if (PFSF_ShowHideOneConditionalField(
                PFSF_conditionalFields[i].antecedantFieldName,
                PFSF_conditionalFields[i].comparisonOperator,
                PFSF_conditionalFields[i].comparisonValue,
                PFSF_conditionalFields[i].consequentFieldName,
                PFSF_conditionalFields[i].defaultValue,
                PFSF_conditionalFields[i].whatToDoWhenHidden))
        {
            if (restartCount++ < 32) // protect against infinite loops
               i = -1; // if one changed, start over
            else alert("Infinite loop averted");
        }

   PFSF_changeStamp++;

   if (dynamicUpdateLevel != undefined && dynamicUpdateLevel > PFSF_dynamicUpdateLevel )
     return;

   PFSF_AjaxUpdateForm();
}

function PFSF_SetupAntecedantFields()
{
  for (var fieldName in FieldIDs)
     PFSF_SetupAntecedantField(PFSF_Find("FIELD_" + FieldIDs[fieldName]));
}

var PFSF_conditionalFields = new Array();

function PFSF_HTMLunescape(s)
{
  return s
   .replace(/&lt;/g, "<")
   .replace(/&gt;/g, ">")
   .replace(/&quot;/g, "\"")  // " to balance the quote for Emacs HTML mode
   .replace(/&#39;/g, "\'")
   .replace(/&amp;/g, "&")
  ;
}

function PFSF_CreateConditionalField(
        antecedantFieldName,
        comparisonOperator,
        comparisonValue,
        consequentFieldName,
        defaultValue,
        whatToDoWhenHidden)
{
    var newObject = new Object();
    newObject.antecedantFieldName = antecedantFieldName;
    newObject.comparisonOperator = comparisonOperator;
    newObject.comparisonValue = PFSF_HTMLunescape(comparisonValue);
    newObject.consequentFieldName = consequentFieldName;
    newObject.defaultValue = PFSF_HTMLunescape(defaultValue);
    newObject.whatToDoWhenHidden = whatToDoWhenHidden;
    PFSF_conditionalFields.push(newObject);
}

// MultiSelect IncludeBox
function MSIB_Process(base, shouldAdd /* true = add, false = remove */)
{
  var e = document.forms[0][base+(shouldAdd?"_EXCLUDE":"_INCLUDE")];
  var a = document.forms[0][base];
  var ei;
  var ai;
  for (ei=0; ei<e.options.length; ei++)
  {
    if (e.options[ei].selected)
      for (ai=0; ai<a.options.length; ai++)
        if (a.options[ai].value == e.options[ei].value)
          a.options[ai].selected = shouldAdd;
  }
  MSIB_Populate(base);
}
function MSIB_Populate(base)
{
  var i = document.forms[0][base+"_INCLUDE"];
  var e = document.forms[0][base+"_EXCLUDE"];
  var a = document.forms[0][base];
  var o = a.options;
  i.options.length = 0;
  e.options.length = 0;
  var u;
  for (u=0; u<o.length; u++)
  {
    var no = new Option(o[u].text, o[u].value);
 
    if (o[u].selected) 
      i.options[i.options.length] = no;
    else
      e.options[e.options.length] = no;
  }
}


// adapted from AdminInteractiveSupport.inc

function PFSF_FindStyleInOneStylesheetAndItsIncludes(stylesheet, selectorText)
{
   var rules = new Array();
   // ns6 and ff don't support the selectorText property - https://bugzilla.mozilla.org/show_bug.cgi?id=51944
   //if (stylesheet.cssRules)
      //rules = stylesheet.cssRules;
   if (stylesheet.rules)
      rules = stylesheet.rules

   for (var i=0; i<rules.length; i++)
      if (rules[i].selectorText.toLowerCase() == selectorText)
          return rules[i];

   var imports = new Array();
   if (stylesheet.imports)
      imports = stylesheet.imports;
   for (var j=0; j<imports.length; j++)
   {
      var retval = PFSF_FindStyleInOneStylesheetAndItsIncludes(
         stylesheet.imports[j], selectorText);
      if (retval != null)
         return retval;
   }
}

var PFSF_styleCache = new Object();

function PFSF_FindStyle(className, elementName)
{
   var selectorText = (elementName + '.' + className).toLowerCase();
   if (PFSF_styleCache[selectorText] != null)
      return PFSF_styleCache[selectorText];

   for (var styleSheetIndex=0; 
        styleSheetIndex<document.styleSheets.length;
        styleSheetIndex++)
   {
      var retval = PFSF_FindStyleInOneStylesheetAndItsIncludes(
         document.styleSheets[styleSheetIndex], selectorText);
      if (retval != null)
      {
         PFSF_styleCache[selectorText] = retval;
         return retval;
      }
   }
   return null;
}

function PFSF_InsertRule(styleSheet, rule, index)
{  
   if (styleSheet.insertRule)  
   {
      styleSheet.insertRule(rule, styleSheet.cssRules.length); // DOM
      return true;
   }
   else if (styleSheet.addRule) 
   {
      styleSheet.addRule(rule.substring(0, rule.indexOf("{")), rule.substring(rule.indexOf("{") + 1, rule.indexOf("}")), index); // IE
      return true;
   }
   return false;
}

function PFSF_DeleteRule(styleSheet, index)
{  
   if (styleSheet.deleteRule)  
   {
      styleSheet.deleteRule(index); // DOM
      return true;
   }
   else if (styleSheet.removeRule) 
   {
      styleSheet.removeRule(index); // IE
      return true;
   }
   return false;
}

