//<SCRIPT> // <- dummy script tag used to enable InterDev syntax coloring
//------------------------------------------------------------------------
// File:    sc_widgets.js
// Authors: Al Yanchak, Jonathan Scott-Sheldon
// Date:    
//
// Revised: 
//
// SmartCAT v3.0 library file
//
// Implements client-side objects for SmartCAT widgets
//
// Copyright© 1999 - 2001 i-MARK Inc. All Rights Reserved
//
// WARNING: The information in this file is protected by copyright law
// and international treaty provisions. Unauthorized reproduction or
// distribution of this file, or any portion of it, may result in severe
// criminal and civil penalties, and will be prosecuted to the maximum
// extent possible under the law.  Further, you may not reverse engineer,
// decompile, or disassemble the file.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Global Functions & Variables
//------------------------------------------------------------------------

var KEY_ENTER = 13;
var CAD_LABEL = 0;
var CAD_DXF_SRC = 1;
var CAD_GIF_SRC = 2;

// bit mask definition for scListFilter2
// describes the many varied states it can be in
var LIST2_DEF = 0;                // behaves exactly like scListFilter with no extended capability
var LIST2_DISP_PARAM = 1;         // a display parameter other than the value parameter is identified
var LIST2_MIN_MAX_VAL_PARAM = 2;  // both min and max param's are identified for list values
var LIST2_MIN_MAX_DISP_PARAM = 4; // both min and max param's are identified for visible list values
var LIST2_MIN_INCLUSIVE = 8;      // the minimum of the min parameter is included in the comparison (>= comp type)
var LIST2_MAX_INCLUSIVE = 16;     // the maximum of the max parameter is included in the comparison (<= comp type)
var LIST2_TOLERANCE_PERCENT = 32; // the tolerance around the comparison is to be treated as a percentage
var LIST2_SORT_PARAM = 64;        // a sort parameter is identified

var LOADLIST_POLLING_LIMIT = 50;
var LOADLIST_POLLING_TIMEOUT = 100;
var LoadList_Polling_Count = -1;
var LoadList_Polling_ID = null;

var g_SQL_symbols = new scSQLSymbols();

function scSQLSymbols()
{
  this.Symbols = new Object();
  this.Insert = scSQLSymbolsInsert;
  this.toString = scSQLSymbolsString;
  this.Clear = scSQLSymbolsClear;
}

function scSQLSymbolsInsert(str_symbol, str_value)
{
  this.Symbols[str_symbol] = str_value;
}

function scSQLSymbolsClear()
{
  this.Symbols = null;
  this.Symbols = new Object();
}

function scSQLSymbolsString()
{
  var str_symbols = new String("");
  
  for (var item in this.Symbols)
    str_symbols += item + "==" + this.Symbols[item] + "|";
  
  return str_symbols;
}

//------------------------------------------------------------------------
// Widget Initialization
//------------------------------------------------------------------------

var sc_arrWidgetInitList = new Array;

function scWidgetInit()
{
  for(var i = 0, len = sc_arrWidgetInitList.length; i < len; i++)
    sc_arrWidgetInitList[i].Init();
    
}

function scWidgetRegisterInit(widgObj)
{
  sc_arrWidgetInitList[sc_arrWidgetInitList.length] = widgObj;
}

//------------------------------------------------------------------------
// scFilterInit
//
// Global function to initialize the Filter Control by creating the one
// (and only) scFilterControl object named 'theFilter'
//------------------------------------------------------------------------
function scFilterInit(famID, str_uom, frmID, initList, isGraphic, isFilterless, isFrameless)
{
  var frmMenu = sc_FindFrame("sc_header");
  var myFamID = famID;
  var myUOM = str_uom;
  var myInitList = (initList) ? initList + "|uom=" + str_uom : "";

  if(frmMenu)
  {
    // if an init list is defined, update the saved selection state
    // otherwise, initialize to the saved selection state 

    if(frmMenu.IsSaveSelState == true)
    {
      if(frmMenu.strSelectionState)
      {
        var result = frmMenu.strSelectionState.match(/famID=(\d+)/);
        if (result)
        {
          if (result[1])
          {
            if (parseInt(famID) == parseInt(result[1]))
            {
              myInitList = frmMenu.strSelectionState;
              result = frmMenu.strSelectionState.match(/uom=(\w{2})/);
              if (result)
                if (result[1])
                  myUOM = result[1];
            }
          }
        }
      }
    }
    else
    {
      if(initList)
        frmMenu.strSelectionState = initList + "|uom=" + str_uom;
    }
    frmMenu.IsSaveSelState = false;
  }
  theFilter = new scFilterControl(famID, myUOM, frmID, isGraphic, isFilterless, isFrameless);
  theFilter.InitList = (myInitList) ? myInitList : "";
}

//------------------------------------------------------------------------
// scLoadFilterValues
//
// Global callback function which routes the Call Object returned from the
// reomote scripting call to the proper filter handler
//------------------------------------------------------------------------
function scLoadFilterValues(co)
{
  var len = theFilter.FilterList.length
  var frameTable = theFilter.IsFrameless ? sc_FindFrame("sc_prod_tbl") : sc_FindFrame("sc_seltable");
  if (!frameTable)
  {

    LoadList_Polling_Count++;
    if (LoadList_Polling_Count < LOADLIST_POLLING_LIMIT)
    {
      LoadList_Polling_ID = setTimeout("scLoadFilterValues()", LOADLIST_POLLING_TIMEOUT);
    }
    else
    {
      for(var i = 0; i < len; i++)
        theFilter.FilterList[i].SetOptions(null);
      theFilter.Reset();
    }
    return false;
  }
  if (!frameTable.theFilterValues && !theFilter.IsFilterless)
  {
    LoadList_Polling_Count++;
    if (LoadList_Polling_Count < LOADLIST_POLLING_LIMIT)
    {
      LoadList_Polling_ID = setTimeout("scLoadFilterValues()", LOADLIST_POLLING_TIMEOUT);
    }
    else
    {
      for(var i = 0; i < len; i++)
        theFilter.FilterList[i].SetOptions(null);
      theFilter.Reset();
    }
    return false;
  }

  LoadList_Polling_ID = null;

  for(var i = 0; i < len; i++)
  {
    if (frameTable.theFilterValues[theFilter.FilterList[i].ID])
      theFilter.FilterList[i].SetOptions(frameTable.theFilterValues[theFilter.FilterList[i].ID]);
    else
      theFilter.FilterList[i].SetOptions(null);
  }
}

function scZImgCtrl()
{
  this.Add          = scAddZImg;
  this.Show         = scShowZImgCtrl;
  this.Hide         = scHideZImgCtrl;
  this.PreLoadZImgs = scPreLoadZImgs;

  this.ZImgList     = new Array;
  
  this.ImgCacheFrame = sc_FindFrame("sc_prod_tbl");
}

function scAddZImg(id,str_CloseMessage,src)
{
  this.ZImgList[this.ZImgList.length] = new scZImg(id,src,str_CloseMessage,this);
}

function scPreLoadZImgs()
{
  if (this.ImgCacheFrame)
    this.ImgCacheFrame.TriggerPreloadZImg();
}

function scShowZImgCtrl(id)
{
  var i;
  for (i = 0; i < this.ZImgList.length; i++)
    if (this.ZImgList[i].id == id)
      break;

  if (i == this.ZImgList.length)
    // the indicated id does not have a zoom image object
    return false;

  this.ZImgList[i].show();
  return false;
}

function scHideZImgCtrl(id)
{
  var i;
  for (i = 0; i < this.ZImgList.length; i++)
    if (this.ZImgList[i].id == id)
      break;
  
  if (i == this.ZImgList.length)
    // the indicated id does not have a zoom image object
    return false;
  
  this.ZImgList[i].hide();
}

function scZImg(id,src,str_CloseMessage,zimgCtrl)
{
  this.id       = id;
  this.src      = src;
  this.ZImgCtrl = zimgCtrl;
  this.CloseMessage = str_CloseMessage;
  this.NormalObject = null;  // this is a reference to the containing object (span) the user clicks
                             // to see the enlarged version

  this.show     = scShowZImg;
  this.hide     = scHideZImg;
  
  if (this.ZImgCtrl.ImgCacheFrame)
    this.ZImgCtrl.ImgCacheFrame.CreatePreloadZImg(id,src);
}

// *** MODIFIED ***
//
// Modified By:  Al Yanchak
// Date:         12/12/2003
//
// Desc: Modified to properly handle Netscape 6+ browsers
function scShowZImg(evt)
{
  var theZImgObj;    
  theZImgObj = (IsNN4) ? document.zimg :
               (IsIE4) ? document.all.zimg :  
                         document.getElementById("zimg");

  // die if we don't get a reference to the container for the enlarged image
  if (!theZImgObj)
    return;

  imkHide(theZImgObj);

  var theHeight;
  var documentX;
  var documentY;
  var docWidth = imkGetDocumentWidth();
  var docHeight = imkGetDocumentHeight();
  var ZImgX;
  var ZImgY;
  var moveX;
  var moveY;
  var str_html;

  var leftX;
  var topY;
  var rightX;
  var bottomY;
      
  // check to be sure we have a reference to the span container the user clicked on
  if (!this.NormalObject)
    this.NormalObject = (IsNN4) ? document["zimg" + this.id] :
                        (IsIE4) ? document.all["zimg" + this.id] :
                                  document.getElementById("zimg" + this.id);

  // if we still do not have a reference to the span container, then die silently
  if (!this.NormalObject)
    return;
    
  // documentX pinpoints the x-coordinate position of the center of the clicked image
  // documentY pinpoints the y-coordinate position of the center of the clicked image
  documentX = imkGetPageX(this.NormalObject) + parseInt(imkGetWidth(this.NormalObject)/2);
  documentY = imkGetPageY(this.NormalObject) + parseInt(imkGetHeight(this.NormalObject)/2);

  if (IsNN4)
  {
    str_html = "<table border='0' cellpadding='2' cellspacing='0'>" +
               "<tr><td bgcolor='gray'>" +
               "<table cellpadding=2 cellspacing=0 width='100%' border=0>" +
               "<tr><td bgcolor='#cccccc' align='right'>" +
               "<a href='javascript:theZImages.Hide(" + this.id + ")'><img src='../images/close.gif' border=0></a>" +
               "</td></tr>" + 
               "<tr><td align='middle' bgcolor='#ffffff'><img src='" + this.src + "'>";

    if (this.CloseMessage)
      str_html += "<BR><a href='javascript:theZImages.Hide(" + this.id + ")'>" + this.CloseMessage + "</a></td></tr></table>";
    else
      str_html += "</td></tr></table>";

    str_html += "</td></tr></table>";

    theZImgObj.document.open();
    theZImgObj.document.write(str_html);
    theZImgObj.document.close();

    ZImgX = imkGetWidth(theZImgObj);
    ZImgY = imkGetHeight(theZImgObj);

  }
  else
  {
    // create an image object to get the height of the to be revealed zoomed image
    // using the imkGetWidth method does not report the correct height until
    // the dhtml object has been made visible on screen and of course this is too late
      
    var imgTemp = new Image();
    imgTemp.src = this.src;
    var int_YoffSet = 30;
    str_html = "<table cellspacing=0 cellpadding=0>" +
               "<tr><td bgcolor='#cccccc' align='right'>" +
               "<a href='javascript:theZImages.Hide(" + this.id + ")'><img src='../images/close.gif' border=0></a>" +
               "</td></tr>" + 
               "<tr><td><img src='" + this.src + "'></td></tr>" +
               "</table>";
                 
    if (this.CloseMessage)
    {
      str_html += "<a href='javascript:theZImages.Hide(" + this.id + ")'>" + this.CloseMessage + "</a>";
      int_YoffSet += 16;
    }

    theZImgObj.innerHTML = str_html;
    
      
    ZImgX = imgTemp.width; // + 8;
    ZImgY = imgTemp.height + int_YoffSet;

    theZImgObj.style.width = ZImgX;
    theZImgObj.style.height = ZImgY;
  }

  leftX = documentX - parseInt(ZImgX/2);
  topY = documentY - parseInt(ZImgY/2);
  rightX = documentX + parseInt(ZImgX/2);
  bottomY = documentY + parseInt(ZImgY/2);
  
  if (bottomY >= docHeight) // accounts for the image being too close to the bottom of the screen
    moveY = docHeight - ZImgY - 20;
  else if (topY <= 0) // accounts for the image being to close to the top of the screen
    moveY = 10;
  else // any other place on the screen
    moveY = documentY - parseInt(ZImgY/2);

  if (rightX >= docWidth) // accounts for the image being too close to the right side of the screen
    moveX = docWidth - ZImgX - 20;
  else if (leftX <= 0) // accounts for the image being too close to the left side of the screen
    moveX = 10;
  else // accounts for any other position on the screen
    moveX = documentX - parseInt(ZImgX/2);

  // there is still the possibility that moveY and moveX could be negative values
  // therefore we must check them and not allow negative values.
  moveY = (moveY <= 0 ? 2 : moveY);
  moveX = (moveX <= 0 ? 2 : moveX);

  imkMoveTo(theZImgObj, moveX, moveY);
  imkShow(theZImgObj);
}

function scHideZImg()
{
  var theZImgObj = (IsNN4) ? document.zimg
                 : (IsIE4) ? document.all.zimg
                           : document.getElementById("zimg");
  imkHide(theZImgObj);
  return;
}

//------------------------------------------------------------------------
// scImgWidget
//
// Implements the Image Widget client-side object and methods
//------------------------------------------------------------------------
function scImgWidget(id, src, roll_src)
{
  this.mouseover = scImgWidget_mouseover;
  this.mouseout  = scImgWidget_mouseout;

  this.ID       = id;
  this.src      = src;
  this.roll_src = roll_src;
}

//------------------------------------------------------------------------
// scImgWidget_mouseover
//
// swaps in the rollover image
//------------------------------------------------------------------------
function scImgWidget_mouseover()
{
  if(this.roll_src)
    document.images["img" + this.ID].src = this.roll_src;
}

//------------------------------------------------------------------------
// scImgWidget_mouseover
//
// swaps in the default image
//------------------------------------------------------------------------
function scImgWidget_mouseout()
{
  if(this.src)
    document.images["img" + this.ID].src = this.src;
}

function scIfrmWidget(id, src)
{
  this.Init = scIfrmWidget_Init;
  
  this.ID  = id;
  this.Src = src;
  
  scWidgetRegisterInit(this);
}

function scIfrmWidget_Init()
{
  if(IsNN4 == true)
  {
    var frmObj = eval("document.ifrmOuter" + this.ID +
                      ".document.ifrmInner" + this.ID);
                      
    if(frmObj)
      frmObj.src = this.Src;
    //alert("Here is the source " + frmObj.src);
  }
}

function scCADWidget(id, is_rasterZoom, strZoomLabel, strZoomImgSrc,strNNInitLabelHTML)
{
  this.Init       = scCADWidget_Init;
  this.AddFile    = scCADWidget_AddFile;
  this.NextFile   = scCADWidget_NextFile;
  this.BackFile   = scCADWidget_BackFile;
  this.SwitchCAD  = scCADWidget_SwitchCAD;
  this.Zoom       = scCADWidget_Zoom;
  this.AddCtrlImg = scCADWidget_AddCtrlImg;
  this.ImgAction  = scCADWidget_ImgAction;
  
  this.ID                  = id;
  this.IsRasterZoomEnabled = is_rasterZoom;
  this.IsSLX               = false;    // is SmartLOOKX?
  this.CurrentIndex        = 0;
  this.ZoomLabel           = strZoomLabel;
  this.ZoomImgSrc          = strZoomImgSrc;
  this.NNInitLabelHTML     = strNNInitLabelHTML;
  
  this.MyViewer            = null;
  this.MyLabel             = null;
  this.MyImage             = null;
  this.arrFileList         = new Array;
  this.objImages           = new Object;
  this.MyZoomWindow;
  
  // register with init list
  scWidgetRegisterInit(this);
}

//------------------------------------------------------------------------
// scCADWidget_Init
//
// Initializes CAD viewer widget
//
// Modified:
//  Date: 9/6/99
//  By:   Al Yanchak
//  Desc: If SLX check fails, adds "Download DXF File" (and link) to the
//        label
//
// *** MODIFIED ***
//
// Modified By:  Al Yanchak
// Date:         12/12/2003
//
// Desc: Modified to properly handle Netscape 6+ browsers
//------------------------------------------------------------------------

function scCADWidget_Init()
{
  if(IsIE4 && IsWin)
  {
    // get reference to the label
    var lblObj = eval("document.all.cadLbl" + this.ID);
    if(lblObj)
      this.MyLabel  = lblObj;
      
    // if SmartLOOKX is available, get e reference to the viewer object
    var slxObj = eval("document.all.SmartLOOK" + this.ID);
    if(slxObj)
    {
      this.MyViewer = eval("document.all.SmartLOOK" + this.ID);
      this.IsSLX = true; 
    }
    else
    {
      // no SmartLOOK, so try for an image object
      var imgObj = eval("document.images['cadImg" + this.ID + "']");
      if(imgObj)
        this.MyImage = imgObj;
        
      this.MyLabel.innerHTML += "<BR><A HREF='" + 
                                this.arrFileList[this.CurrentIndex][CAD_DXF_SRC] +
                                "'>Download DXF File</A></DIV>";
      document.all['cadDwnLd' + this.ID].innerHTML = eval("str_downloadMessage" + this.ID);
    }
  }
  else if(IsNN4)
  {
    var imgObj = eval("document.cadImgOuter" + this.ID + ".document.cadImgInner" + this.ID + ".document");
    if(imgObj)
      this.MyViewer = imgObj;
      
    var lblObj = eval("document.cadLblOuter" + this.ID + ".document.cadLblInner" + this.ID + ".document");
    if(lblObj)
    {
      this.MyLabel = lblObj;
      // Rollovers do not function in Netscape with an nested ilayer and layer unless
      // the contents of the inner layer are dynamically flowed to it
      // replacing the original contents.  For some reason, if there is static HMTL inside the
      // inner layer its document.images collection is not populated
      // By dynamically writing the contents of the nested layer its document.images collection is created
      // Netscape really, really sucks.
      this.MyLabel.open();
      this.MyLabel.write(this.NNInitLabelHTML);
      this.MyLabel.close();
    }
  }
  else
  {
    // get reference to the image label
    var imgObj = eval("document.images['cadImg" + this.ID + "']");
    if(imgObj)
      this.MyImage = imgObj;
      
    var lblObj = document.getElementById("cadLbl" + this.ID);
    if(lblObj)
      this.MyLabel  = lblObj;
      
    this.IsSLX = false;
  }
}

function scCADWidget_AddFile(src, label)
{
  var i = this.arrFileList.length;
  this.arrFileList[i] = new Array;
  this.arrFileList[i][CAD_LABEL] = label;
  
  // can't match at first character (index 0) and have
  // a valid file name
  if(src.search(/.dxf/i) > 0)
  {
    // dxf file found, we can assume a gif will be present also
    this.arrFileList[i][CAD_DXF_SRC] = src;
    this.arrFileList[i][CAD_GIF_SRC] = src.replace(/.dxf/i, ".gif");
  }
}

function scCADWidget_AddCtrlImg(strCtrlType,strCtrlImgSrc,strCtrlImgRollSrc)
{
  this.objImages[strCtrlType] = new Object;

  if (strCtrlImgSrc != "")
  {
    this.objImages[strCtrlType]["_off"] = new Image();
    this.objImages[strCtrlType]["_off"].src = strCtrlImgSrc;
    this.objImages[strCtrlType]["isRollover"] = false;

    if (strCtrlImgRollSrc != "")
    {
      this.objImages[strCtrlType]["isRollover"] = true;
      this.objImages[strCtrlType]["_on"] = new Image();
      this.objImages[strCtrlType]["_on"].src = strCtrlImgRollSrc;
    }

  }
}

function scCADWidget_ImgAction(strCtrlType,strAction)
{
  if (document.images && this.objImages[strCtrlType]["isRollover"])
  {
    if (IsNN4 == true && strCtrlType == "zoom")
      this.MyLabel.images[strCtrlType + this.ID].src = this.objImages[strCtrlType][strAction].src;
    else
      document.images[strCtrlType + this.ID].src = this.objImages[strCtrlType][strAction].src;
  }
}

function scCADWidget_NextFile()
{
  this.SwitchCAD(1);
}


function scCADWidget_BackFile()
{
  this.SwitchCAD(-1);
}

// *** MODIFIED ***
//
// Modified By:  Al Yanchak
// Date:         12/12/2003
//
// Desc: Modified to properly handle Netscape 6+ browsers
function scCADWidget_SwitchCAD(stepDir)
{
  if(stepDir > 0)
  {
    this.CurrentIndex++;
    if(this.CurrentIndex == this.arrFileList.length)
      this.CurrentIndex = 0;
  }
  else
  {
    this.CurrentIndex--;
    if(this.CurrentIndex < 0)
      this.CurrentIndex = this.arrFileList.length - 1;
  }
  
  var strZoomLabel;
  
  if (this.ZoomImgSrc)
  {
    strZoomLabel = "<BR><A HREF='javascript:cadWidget" + this.ID + ".Zoom();' " +
                   "ONMOUSEOVER=\"cadWidget" + this.ID + ".ImgAction('zoom','_on');\" " +
                   "ONMOUSEOUT=\"cadWidget" + this.ID + ".ImgAction('zoom','_off');\">" +
                   "<IMG SRC='" + this.ZoomImgSrc + "' NAME='zoom" + this.ID + "' ID='zoom" + this.ID + "' BORDER=0>" +
                   "</A>";
  }
  else
  {
    strZoomLabel = "<BR><A HREF='javascript:cadWidget" + this.ID + ".Zoom();'>" +
                   this.ZoomLabel + "</A>";
  }
  
  if(IsNN4 == true)
  {
    var viewerHeight = eval("document.cadImgOuter" + this.ID).clip.height;
    if(this.MyViewer != null)
    {
      this.MyViewer.open();
      this.MyViewer.write("<HTML><BODY><TABLE BORDER='0' WIDTH='100%'><TR> \
                           <TD CLASS='cadWin" + this.ID +
                          "' WIDTH='100%' HEIGHT='" + 
                          viewerHeight + "' ALIGN='center' VALIGN='middle'> \
                           <IMG SRC='" + this.arrFileList[this.CurrentIndex][CAD_GIF_SRC] +
                          "'></TD></TR></TABLE></BODY></HTML>")
      this.MyViewer.close();
    }
    
    if(this.MyLabel != null)
    {
      var strRasterZoom;
      if(this.IsRasterZoomEnabled == true)
        strRasterZoom = strZoomLabel;
      else
        strRasterZoom = "";
                        
      this.MyLabel.open();
      this.MyLabel.write("<HTML><BODY><TABLE BORDER='0' WIDTH='100%'><TR> \
                          <TD CLASS='cadLbl" + this.ID + "' WIDTH='100%' \
                          HEIGHT='100%' ALIGN='center' VALIGN='middle'>"
                         + this.arrFileList[this.CurrentIndex][CAD_LABEL] + strRasterZoom + 
                         "<BR><A HREF='" + this.arrFileList[this.CurrentIndex][CAD_DXF_SRC] +
                         "'>Download DXF File</A>\
                         </TD></TR></TABLE></BODY></HTML>");
      this.MyLabel.close();
    }
  }
  else
  {
    if(this.IsSLX == true)
    {
      if(this.MyViewer != null) 
        this.MyViewer.DataPath = this.arrFileList[this.CurrentIndex][CAD_DXF_SRC];
    
      if(this.MyLabel != null)
      {                  
        this.MyLabel.innerHTML = this.arrFileList[this.CurrentIndex][CAD_LABEL] + strZoomLabel
      }
    }
    else
    {
      if(this.MyImage != null)
        this.MyImage.src = this.arrFileList[this.CurrentIndex][CAD_GIF_SRC];
    
      if(this.MyLabel != null)
      { 
        if(this.IsRasterZoomEnabled == true)
          strRasterZoom = strZoomLabel;
        else
          strRasterZoom = "";
                           
        this.MyLabel.innerHTML = this.arrFileList[this.CurrentIndex][CAD_LABEL] + 
                                 strRasterZoom + "<BR><A HREF='" + 
                                 this.arrFileList[this.CurrentIndex][CAD_DXF_SRC] +
                                 "'>Download DXF File</A></DIV>"
      }
    }
  } 
}

//------------------------------------------------------------------------
// scCADWidget_Zoom
//
// Opens a zoom window for the CAD viewer or double sized raster image
// for non SLX enabled sessions
//
// Modified:
//  Date: 9/6/99
//  By:   Al Yanchak
//  Desc: Corrected IE implementation of the raster zoom option (for
//        browsers w/out SLX installed)
//------------------------------------------------------------------------

function scCADWidget_Zoom()
{
  if(this.IsSLX == true)
  {
    var height = this.MyViewer.height * 2;
    var width  = this.MyViewer.width * 2;
        
    var prtNo = encodeURI(this.arrFileList[this.CurrentIndex][CAD_DXF_SRC]);
    this.MyZoomWindow = window.open("sc_cadpop.asp?prtNo=" + prtNo + 
                                    "&bgColor=" + this.MyViewer.BackColor,
                                    "cadpop", "HEIGHT=" + height + 
                                    ",WIDTH=" + width + 
                                    ",RESIZABLE");
    if(this.MyZoomWindow)
      this.MyZoomWindow.focus();                                    
  }
  else if(this.IsRasterZoomEnabled == true)
  {
    var height;
    var width;
    var str_bgColor;
    if(IsNN4 == true)
    {
      height = eval("document.cadImgOuter" + this.ID).clip.height * 2;
      width  = eval("document.cadImgOuter" + this.ID).clip.width * 2;
      
      str_bgColor = this.MyViewer.bgColor;
    }
    else
    {
      height = this.MyImage.height * 2;
      width  = this.MyImage.width * 2;
      
      str_bgColor = imkGetLastStyleAttr(".cadWin" + this.ID, "backgroundColor");
    }
    
    var pos = this.arrFileList[this.CurrentIndex][CAD_GIF_SRC].lastIndexOf("/");
    if(pos > 0)
    {
      prtNo = this.arrFileList[this.CurrentIndex][CAD_GIF_SRC].substr(0, pos + 1);
      prtNo = prtNo + "z_" + this.arrFileList[this.CurrentIndex][CAD_GIF_SRC].substr(pos + 1);
    }
    this.MyZoomWindow = window.open("sc_cadpop.asp?prtNo=" + prtNo + 
                                    "&bgColor=" + encodeURI(str_bgColor) +
                                    "&cellHeight=" + height,
                                    "cadpop", "HEIGHT=" + height + 
                                    ",WIDTH=" + width);
    if(this.MyZoomWindow)
      this.MyZoomWindow.focus();                   
  } 
}

//------------------------------------------------------------------------
// scFilterControl
//
// The scFilterControl object serves as the main switchboard directing
// the filter handlers for the page. There may be only one scFilterControl
// object per page
//
// To Do:
//    - implement poll limit (timeout)
//------------------------------------------------------------------------
function scFilterControl(famID, str_uom, frmID, isGraphic, isFilterless, isFrameless)
{
  this.Init               = scFilterControl_Init;
  this.AddFilter          = scFilterControl_AddFilter;
  this.CheckUpdating      = scFilterControl_CheckUpdating;
  this.CheckChanged       = scFilterControl_CheckChanged;
  this.UpdateAll          = scFilterControl_UpdateAll;
  this.InitAll            = scFilterControl_InitAll;
  this.LoadAll            = scFilterControl_LoadAll;
  this.StartPoll          = scFilterControl_StartPoll;
  this.StatusPoll         = scFilterControl_StatusPoll;
  this.StatusPollHandler  = scFilterControl_StatusPollHandler;
  this.ResetValues        = scFilterControl_ResetValues;
  this.Reset              = scFilterControl_Reset;
  this.UpdateUOM          = scFilterControl_UpdateUOM;
  this.TableUpdate        = scFilterControl_TableUpdate;
  this.SaveSelState       = scFilterControl_SaveSelState;
  this.SaveState          = scFilterControl_SaveState;
  this.RotateFocus        = scFilterControl_RotateFocus;
  
  this.FamID          = famID;      // catalog family ID
  this.FormID         = frmID;      // ID of form containing selection widgets
  this.IsGraphic      = Boolean(isGraphic);    // true if graphic based selection table
  this.IsFilterless   = Boolean(isFilterless); // true if no filters are present on this page
  this.IsFrameless    = Boolean(isFrameless);  // true if results window does not use iframe/nested frames
  this.FilterList     = new Array;  // list of all filter handlers
  this.IsUpdating     = false;      // current updating status
  this.TableUpdateReq = false;
  this.IsTableLoading = false;
  this.strSQLCond     = "";
  this.strFiltParams  = "";
  this.strCurPage     = "";
  this.strSortDir     = "";
  this.strSortParam     = "";    
  this.strUOM         = str_uom;
  this.InitList       = "";
  this.FocusTarget    = null;
  
  this.PollID;
  this.POLLING_PERIOD = 75;
  this.POLL_LIMIT = 60 * 1000 / this.POLLING_PERIOD;
  this.PollCount;
  
  this.arrSpinner = new Array;
  this.arrSpinner[0] = "|";
  this.arrSpinner[1] = "/";
  this.arrSpinner[2] = "--";
  this.arrSpinner[3] = "\\";
  
  // register with init list
  scWidgetRegisterInit(this);
}

//------------------------------------------------------------------------
// scFilterControl_Init
//
// Filter control initialization
//------------------------------------------------------------------------
function scFilterControl_Init()
{
  // register keypress handler



  if(IsNN4 == true)
    document.captureEvents(Event.KEYPRESS);

  document.onkeypress = scCheckEnter;
  
  var objUOMOpt;
  if(IsNN6)
    objUOMOpt = document.getElementById("optUOM");
  else
    objUOMOpt = eval("document." + this.FormID + ".optUOM");
    
  if (this.InitList != "")
  {
    if (this.InitList.search(/uom/) != -1)
    {
      var result = this.InitList.match(/uom=(\w{2})/);
      if (result)
        if (this.strUOM != result[1]) 
          this.strUOM = result[1];
      this.LoadAll();
    }
  }

  if(objUOMOpt)
    imkSetOptionValue(objUOMOpt, this.strUOM);
  
  if(this.InitList != "")
  {
    var arrParams = new Array;
    var len = this.FilterList.length;
    for(var j = 0; j < len; j++)
      arrParams[j] = "";
    var isForceUpdate = true;
    
    var arr_initValues = this.InitList.split("|");
    var init_len = arr_initValues.length;
    for(var i = 0; i < init_len; i++)
    {
      var pos = arr_initValues[i].indexOf("=");
      if(pos > 0)
      {
        var param_id  = arr_initValues[i].substr(0, pos);
        var param_val = arr_initValues[i].substr(pos + 1);
        
        if (param_id == "uom")
        {
          if (objUOMOpt)
            imkSetOptionValue(objUOMOpt, param_val);
          this.strUOM = param_val;
        }

        var fltID;
        for(var j = 0; j < len; j++)
        {
          if(this.FilterList[j].ParamID == param_id)
          {
            arrParams[j] = param_val;
            isForceUpdate = false;
            break;
          }
        }
      }
    }
        
    for(var j = 0; j < len; j++)
       this.FilterList[j].Init(arrParams[j], true);
             
    this.UpdateAll(isForceUpdate);

  }
  else
  {
    this.InitAll();
  }
}


//------------------------------------------------------------------------
// scFilterControl_AddFilter
//
// Registers a new filter handler by adding it to the internal list
//------------------------------------------------------------------------
function scFilterControl_AddFilter(fltrObj)
{
  var i = this.FilterList.length
  this.FilterList[i] = fltrObj;
}

//------------------------------------------------------------------------
// scFilterControl_CheckUpdating
//
// Checks the update status of all filter handlers registered for this
// page. Sets this.IsUpdating to false (and returns false) only if both
// this.IsTableLoading AND the IsUpdating memeber for ALL filters are 
// false.
//------------------------------------------------------------------------
function scFilterControl_CheckUpdating()
{
  this.IsUpdating = this.IsTableLoading;
  
  
/*  var len = this.FilterList.length
  for(var i = 0; i < len; i++)
    if(this.FilterList[i].IsUpdating == true)
      this.IsUpdating = true; */

  return this.IsUpdating
}

function scFilterControl_CheckChanged()
{
  var isChanged = false;
  var len = this.FilterList.length
  for(var i = 0; i < len; i++)
  { 
    objFilter = this.FilterList[i]
    if(objFilter.OldValue != objFilter.GetValue())
    {
      if(this.IsUpdating == true)
      {
        objFilter.ResetOld();
      }
      else
      {
        isChanged = true;
        break;
      }
    }
  }

  return isChanged;
}

function scFilterControl_ResetValues()
{
  var len = this.FilterList.length
  for(var i = 0; i < len; i++)
    this.FilterList[i].ResetOld();
}

//------------------------------------------------------------------------
// scFilterControl_UpdateAll
//
// Initiates updating of all of the filter handlers registerd for this
// page
//------------------------------------------------------------------------
function scFilterControl_UpdateAll(isForceUpdate)
{

  // check to see if we any of the filter choices
  // changed, if already updating, reset it
  if(this.CheckChanged() == true || isForceUpdate == true)
  {
    // validate the input
    var len = this.FilterList.length
    for(var i = 0; i < len; i++)
    {
      if(this.FilterList[i].Validate() != true)
      {
        // reset the focus to the offending filter before calling it quits
        this.FilterList[i].SetFocus();
        return;
      }
    }  
    
    this.IsUpdating = true;

    // update all filters
    for(var i = 0; i < len; i++)
      this.FilterList[i].Update();
    
    // and update the selection table
    this.strSQLCond = "";
    this.strFiltParams = "";
    var objFilter;
    var strStateVar = "";
    
    var len = this.FilterList.length;
    for(var i = 0; i < len; i++)
    { 
      objFilter = this.FilterList[i];
      this.strSQLCond += objFilter.GetSQLCond();
      this.strFiltParams += objFilter.GetFiltParamStr() + "|";
      
      if(objFilter.GetValue() != "")
        strStateVar += objFilter.ParamID + "=" + objFilter.GetValue() + "|";
    }
        
    var objUOMOpt = eval("document." + this.FormID + ".optUOM");
    if(objUOMOpt)
      strStateVar += "uom=" + imkGetOptionValue(objUOMOpt);

    this.SaveSelState(strStateVar + "|famID=" + this.FamID);
    this.StartPoll();
    this.TableUpdate();
  }
}

function scFilterControl_InitAll()
{
  if(this.IsUpdating == true)
    return;
  
  this.IsUpdating = true;
  this.strSQLCond = "";
  this.strFiltParams = "";
  this.strTblParams = "";
  
  var objUOMOpt = eval("document." + this.FormID + ".optUOM");
  if(objUOMOpt)
    imkSetOptionValue(objUOMOpt, this.strUOM);
  
  var len = this.FilterList.length;
  for(var i = 0; i < len; i++)
    this.FilterList[i].Init("", false);
    
  // after all the filters have been initialized
  // build the FiltParams string
  for(var i = 0; i < len; i++)
    this.strFiltParams += this.FilterList[i].GetFiltParamStr() + "|";

  this.SaveSelState("uom=" + this.strUOM + "|famID=" + this.FamID);
  this.StartPoll();
  this.TableUpdate();
}

function scFilterControl_LoadAll(isEmpty)
{
  if(this.IsUpdating == true)
    return;

  for(var j = 0, len = this.FilterList.length ; j < len; j++)
     this.FilterList[j].Init("", false);

  if (!isEmpty)
    scLoadFilterValues();
}

function scFilterControl_SaveState()
{
  // and update the selection table
  var objFilter;
  var strStateVar = "";
    
  var len = this.FilterList.length;
  for(var i = 0; i < len; i++)
  { 
    objFilter = this.FilterList[i];
      
    if(objFilter.GetValue() != "")
      strStateVar += objFilter.ParamID + "=" + objFilter.GetValue() + "|";
  }
    
  var objUOMOpt = eval("document." + this.FormID + ".optUOM");
  if(objUOMOpt)
    strStateVar += "uom=" + imkGetOptionValue(objUOMOpt);

  this.SaveSelState(strStateVar + "|famID=" + this.FamID);
}

function scFilterControl_SaveSelState(strSelState)
{
  var frmMenu = sc_FindFrame("sc_header");
  if(frmMenu)
    frmMenu.strSelectionState = strSelState;
}

function scFilterControl_TableUpdate()
{
  this.TableUpdateReq = true;
  this.IsTableLoading = true;
}

function scFilterControl_StartPoll()
{
  this.PollCount = 0;  
  if(document.images && !this.IsFilterless)
    document.images["comp_ani"].src = "../sc_images/comp_ani.gif";
  this.StatusPoll();
}

function scFilterControl_StatusPoll()
{
  this.PollID =  window.setTimeout('theFilter.StatusPollHandler()', this.POLLING_PERIOD); 
}

function  scFilterControl_StatusPollHandler()
{
  if(this.CheckUpdating() == true)
  {
    this.PollCount++;
    window.status = "Updating Filter Selections " + this.arrSpinner[this.PollCount % 4];
    
    if(this.TableUpdateReq == true)
    {
      var tblFrame = sc_FindFrame("sc_prod_tbl");
      if(tblFrame != null && tblFrame.CheckReady)
      {
        if(tblFrame.CheckReady(this.IsFrameless) == true)
        {
          tblFrame.Update(this.FamID,
                          view_code,
                          encodeURI(this.strSQLCond),
                          encodeURI(this.strFiltParams),
                          this.strUOM,
                          this.IsFrameless,
                          encodeURI(g_SQL_symbols.toString()).replace('&','%26').replace('#','%23'));
                          
          this.IsTableLoading = true;
          this.TableUpdateReq = false;
        }
      }
    }    
    this.StatusPoll();
  }
  else
  {
    this.IsUpdating = false;
         
    // if the old value was not found in the new list
    // then one of the other filters must have changed the
    // contents of this one - we need to go around again
    if(this.CheckChanged() == true)
    {
      theFilter.UpdateAll();
      return;
    }
    
    scLoadFilterValues();
    
    window.status = "Done"
    if(document.images && !this.IsFilterless)
      document.images["comp_ani"].src = "../sc_images/comp_blank.gif";
      
    if(this.FocusTarget != null)
      this.FocusTarget.SetFocus();
  }
}

function scFilterControl_Reset()
{
  var len = this.FilterList.length;
  this.strFiltParams = "";
  
  for(var i = 0; i < len; i++)
    this.FilterList[i].ResetFilter();

  for(var i = 0; i < len; i++)
    this.strFiltParams += this.FilterList[i].GetFiltParamStr() + "|";

  this.SaveSelState("uom=" + this.strUOM + "|famID=" + this.FamID);
  this.strSQLCond = "";
  
  //MikeC addd to make sure hidden filters don't lose there values.
  for(var i = 0; i < len; i++)
  {
    if (this.FilterList[i].GetType() == "hid")
        this.strSQLCond = this.strSQLCond + "param" + this.FilterList[i].GetParamID() + "='" + this.FilterList[i].GetValue() + "' AND "  
  }  
  
  var frmMenu = sc_FindFrame("sc_header");
  if (frmMenu)
    if (frmMenu.selected_parts)
     frmMenu.selected_parts = "";
  this.TableUpdate(); 
  this.StartPoll(); 
}

function scFilterControl_UpdateUOM(str_uom)
{
  if(this.IsUpdating == true)
  {
    // reset and return
    // check for exitance of optUOM widget, should always exist
    // if we are responding to an UpdateUOM event
    var objUOMOpt = eval("document." + this.FormID + ".optUOM");
    if(objUOMOpt)
      imkSetOptionValue(objUOMOpt, this.strUOM);
      
    return;
  }

  this.strUOM = str_uom;
  
  var strSelTblSrc
  if (this.IsGraphic == "true")
    strSelTblSrc = "sc_seltblgrfx.asp?famID=" + this.FamID + "&vid=" + view_code + "&UOM=" + this.strUOM + "&strFiltParams=" + encodeURI(this.strFiltParams);
  else
    strSelTblSrc = "sc_seltbl.asp?famID=" + this.FamID + "&vid=" + view_code + "&UOM=" + this.strUOM + "&strFiltParams=" + encodeURI(this.strFiltParams);

  sc_ReplaceLocation(strSelTblSrc, "sc_prod_tbl")
  
  var tblFrame = sc_FindFrame("sc_prod_tbl")
    if(tblFrame != null)
      tblFrame.IsReady = false;
  
  this.InitAll();
}

function scFilterControl_RotateFocus(id)
{
  if(this.IsUpdating == true)
    return;
    
  var len = this.FilterList.length
  if(len > 1)
  {
    for(var i = 0; i < len; i++)
    {
      if(this.FilterList[i].ID == id)
      {
        var j = i + 1;
        if(j >= len)
          j = 0;
        this.FilterList[j].SetFocus();
        break;
      }
    }
  }
  else
  {
    this.FilterList[0].Blur();
    this.FilterList[0].SetFocus();
  }
}

//------------------------------------------------------------------------
// scListFilter
//
// Implements the client side filter handler object associated with a 
// selection list
//------------------------------------------------------------------------
function scListFilter(id, paramID, paramType, sortParam, fltrCtrl, label)
{
  this.Update           = scListFilter_Update;
  this.GetType          = scListFilter_GetType;    
  this.GetValue         = scListFilter_GetValue;
  this.GetParamID       = scListFilter_GetParamID;    
  this.SetValue         = scListFilter_SetValue;
  this.SetOptions       = scListFilter_SetOptions;
  this.Init             = scListFilter_Init;
  this.ResetOld         = scListFilter_ResetOld;
  this.ResetFilter      = scListFilter_ResetFilter;
  this.OnFocus          = scListFilter_OnFocus;
  this.OnChange         = scListFilter_OnChange;
  this.Validate         = scListFilter_Validate;
  this.SetFocus         = scListFilter_SetFocus;
  this.Blur             = scListFilter_Blur;
  
  this.GetFiltParamStr  = scListFilter_GetFiltParamsStr;
  this.GetSQLCond       = scFilterBase_GetSQLCond;
  this.label            = label; 
  this.ID               = id;        // the ID of this filter control object
  this.ParamID          = paramID;   // the paramater this object is bound to
  if (sortParam == -1)
    {
     sortParam = paramID;
  }
  this.SortParam        = sortParam; // field to sort select paramaters on
  this.ParamType        = paramType; // the paramater type
  this.FilterControl    = fltrCtrl;  // the parent filter control object
  this.MatchExact       = "Yes";     // always "Yes" for ListFilters
  this.CompType         = "=";       // always '=' for ListFilters
  this.CO               = null;      // remote scripting call object
  this.MinusTolerance   = 0;
  this.PlusTolerance    = 0;

  // internal pointer to the list object
  this.MyList;
  
  this.IsUpdating = false;
  this.OldValue;
  
  this.FilterControl.AddFilter(this); // self register
}

function scListFilter_Update()
{ 
  this.OldValue = this.GetValue();
  this.IsUpdating = true;
  return true;
}

function scListFilter_GetType()
{
  return 'list';
}

function scListFilter_Init(initialCond, isIC)
{
  this.OldValue = ""
    
  // grab an internal pointer to the list object
  if(!this.MyList)
    this.MyList = eval("document." + this.FilterControl.FormID + ".flt" + this.ID);
  
  this.MyList.options[0].selected = true;
  
  if(isIC)
    this.SetValue(initialCond);
  else
    this.IsUpdating = true;   
}

function scListFilter_GetFiltParamsStr()
{
  var objFilter;
  var strSQLCond = "";
  
  var len = this.FilterControl.FilterList.length;
  for(var i = 0; i < len; i ++)
  { 
    objFilter = this.FilterControl.FilterList[i];
    if(objFilter != this)
      strSQLCond = strSQLCond + objFilter.GetSQLCond();
  }

  return this.ID + "^list^" + this.ParamID + "^" + this.SortParam + "^" + strSQLCond;
}

function scListFilter_GetValue()
{
  if (this.label)
  {
      if(this.MyList.selectedIndex > 1)
        return this.MyList.options[this.MyList.selectedIndex].value
      else
        return ""
  }
  else
  {
      if(this.MyList.selectedIndex >= 0)
        return this.MyList.options[this.MyList.selectedIndex].value
      else
        return ""  
  }
}

function scListFilter_GetParamID()
{
  return this.ParamID;
}
function scListFilter_SetValue(val)
{
  var isInList = false;
  var len = this.MyList.options.length;
  for(i = 0; i < len; i++)
  {
    if(this.MyList.options[i].value == val)
    {
      this.MyList.options[i].selected = true;
      isInList = true;
      break;
    }
  }
  
  // if not found, need to add it back in
  if(isInList == false)
  {  
    this.MyList.options[len] = new Option(val, val, false, false);
    this.MyList.options[len].selected = true;
  }
}

function scListFilter_ResetOld()
{
  var len = this.MyList.options.length;
  for(i = 0; i < len; i++)
  {
    if(this.MyList.options[i].value == this.OldValue)
    {
      this.MyList.options[i].selected = true;
      break;
    }
  }
}  

function scListFilter_SetOptions(co)
{
  var len;

  if (co != null)  
    co = unescapeHTML(co)
  // split the result string into an array
//  var optionsArray = co.return_value.split("|");
  var optionsArray;
  if (co != null)
    optionsArray = co.split("|");

  // delete the old list entries
  len = this.MyList.options.length - 1;
  for(var i = len; i > 0; i--)
  {
    this.MyList.options[i] = null;
  }

  if (co != null)
  {
    // set the new ones
    len = optionsArray.length;

    //if we show label in as the first option
    if (this.label) {

        this.MyList.options[0] = new Option(this.label, "", false, false);
        this.MyList.options[1] = new Option("", "", false, false);
        for(i = 0; i < len; i++)
        {
          if(optionsArray[i] != "")
            this.MyList.options[i + 2] = new Option(optionsArray[i], optionsArray[i], false, false);
        }        
    }
    else
    {
        for(i = 0; i < len; i++)
        {
          if(optionsArray[i] != "")
            this.MyList.options[i + 1] = new Option(optionsArray[i], optionsArray[i], false, false);
        }        
    }
    
  }
  // now reset the selected option to the original value
  // Note: should always be in the new list
  this.ResetOld();
  this.IsUpdating = false;
}

function scListFilter_ResetFilter()
{
  this.OldValue = "";
  if(this.MyList)
    this.MyList.options[0].selected = true;
  this.IsUpdating = true;
}

function scListFilter_OnFocus()
{
  this.FilterControl.FocusTarget = this;
  if(this.FilterControl.IsUpdating == true)
    this.MyList.blur();
}


function scListFilter_OnChange()
{       
  this.FilterControl.UpdateAll();
}

function scListFilter_Validate()
{
  return true;
}

function scListFilter_SetFocus()
{
  this.MyList.focus();
}

function scListFilter_Blur()
{
  this.MyList.blur();
}

//------------------------------------------------------------------------
// scListFilter2
//
// Implements the client side filter handler object associated with a 
// selection list
//------------------------------------------------------------------------
function scListFilter2(id, 
                       minValParamID, 
                       maxValParamID,
                       minDispParamID,
                       maxDispParamID,
                       minusTolerance,
                       plusTolerance,
                       paramType,
                       typeMask,
                       strCompType,
                       sortParam,
                       fltrCtrl)
{
  this.Update           = scListFilter_Update;
  this.GetValue         = scListFilter_GetValue;
  this.GetType          = scListFilter2_GetType;    
  this.SetValue         = scListFilter2_SetValue;
  this.SetOptions       = scListFilter2_SetOptions;
  this.GetOptions       = scListFilter2_GetOptions;
  this.Init             = scListFilter2_Init;
  this.ResetOld         = scListFilter_ResetOld;
  this.ResetFilter      = scListFilter_ResetFilter;
  this.OnFocus          = scListFilter_OnFocus;
  this.OnChange         = scListFilter_OnChange;
  this.Validate         = scListFilter_Validate;
  this.SetFocus         = scListFilter_SetFocus;
  this.Blur             = scListFilter_Blur;
  
  this.GetFiltParamStr  = scListFilter2_GetFiltParamsStr;
  this.GetSQLCond       = scFilterBase2_GetSQLCond;

  // set properties
  this.ID               = id;             // the ID of this filter control object
  this.MinValParamID    = minValParamID;  // the (min) value parameter this object is bound to
  this.MaxValParamID    = maxValParamID;  // the paramater this object is bound to
  this.MinDispParamID   = minDispParamID; // the displaye parameter this object is bound to
  this.MaxDispParamID   = maxDispParamID; // the paramater this object is bound to
  this.SortParam        = sortParam;      // field to sort select paramaters on
  this.ParamType        = paramType;      // the paramater type
  this.FilterControl    = fltrCtrl;       // the parent filter control object
  this.MatchExact       = null;           // does not make sense in this context
  this.CompType         = strCompType;    // can be < OR > OR <= OR >=, only applies in non-range types
  this.MinCompType      = "<";           // range types only
  this.MaxCompType      = ">";           // range types only
  this.CO               = null;           // remote scripting call object
  this.MinusTolerance   = minusTolerance; // only applies in non-range types
  this.PlusTolerance    = plusTolerance;  // only applies in non-range types
  this.TypeMask         = typeMask;       // Integer Mask describing the functionality of the filter object

  // internal pointer to the list object
  this.MyList;
  
  this.IsUpdating = false;
  this.OldValue;
  
  this.FilterControl.AddFilter(this); // self register
}


function scListFilter2_GetType()
{
  return 'list2';
}


function scListFilter2_Init(initialCond, isIC)
{
  this.OldValue = ""
    
  // grab an internal pointer to the list object
  if(!this.MyList)
    this.MyList = eval("document." + this.FilterControl.FormID + ".flt" + this.ID);
  
  this.MyList.options[0].selected = true;
  
  if (this.TypeMask & LIST2_MIN_INCLUSIVE)
    this.MinCompType = "<=";
  
  if (this.TypeMask & LIST2_MAX_INCLUSIVE)
    this.MaxCompType = ">=";
  
  if(isIC)
    this.SetValue(initialCond);
  else
    this.IsUpdating = true;   
}

function scListFilter2_GetFiltParamsStr()
{
  var objFilter;
  var strSQLCond = "";
  
  var len = this.FilterControl.FilterList.length;
  for(var i = 0; i < len; i ++)
  { 
    objFilter = this.FilterControl.FilterList[i];
    if(objFilter != this)
      strSQLCond = strSQLCond + objFilter.GetSQLCond();
  }

  return this.ID + "^list2^" + 
         this.MinValParamID + "^" + 
         this.MaxValParamID + "^" + 
         this.MinDispParamID + "^" + 
         this.MaxDispParamID + "^" + 
         this.SortParam + "^" + 
         this.TypeMask + "^" +
         strSQLCond;
}

function scListFilter2_SetOptions(co)
{
  var len;
  var i, j;
  
  // split the result string into an array
//  var optionsArray = co.return_value.split("|");
  var optionsArray;
  if (co != null)
    optionsArray = this.GetOptions(co); //co.split("|");

  // delete the old list entries
  len = this.MyList.options.length - 1;
  for(i = len; i > 0; i--)
  {
    this.MyList.options[i] = null;
  }
  
  if (co != null) // set the new ones
    for (i = 0, len = optionsArray.length; i < len; i++)
      this.MyList.options[i+1] = new Option(optionsArray[i].text, optionsArray[i].value, false, false);

  // now reset the selected option to the original value
  // Note: should always be in the new list
  this.ResetOld();
  this.IsUpdating = false;
}

/*
   builds an array of objects which are all the values to be popped onto the drop down list
   Hides all the ugly decision making that goes into creating the drop down list so that the
   function scListFilter2_SetOptions is cleaner.
*/
function scListFilter2_GetOptions(optionsList)
{
    var i, j;
    var optionsArray = optionsList.split("|");
    var len = optionsArray.length;
    
    var retArray = new Array();
    
    if (this.TypeMask & LIST2_MIN_MAX_DISP_PARAM)
    {
      // values must be sorted since the SQL will not return an ordered recordset from the two parameters
      // they are to be sorted on the values that the user will see
      var optionsArraySort = new Array();
      var options = new Object();
      len--;  // decrease length by one since moving through the list 2 at a time
      for(i = 0, j = 0; i < len; i+=2)
      {
        if(optionsArray[i] != "" && optionsArray[i + 1] != "")
        {
          optionsArraySort[j++] = optionsArray[i + 1];
          options[optionsArray[i + 1]] = optionsArray[i];
        }
      }
      if (this.ParamType == "txt")
        optionsArraySort.sort();
      else
        optionsArraySort.sort(function(a,b){ return a-b;});
      
      for (i = 0, len = optionsArraySort.length; i < len; i++)
      {
        retArray[i] = new Object();
        retArray[i].text = optionsArraySort[i];
        retArray[i].value = options[optionsArraySort[i]];
      }
    }
    else if (this.TypeMask & LIST2_MIN_MAX_VAL_PARAM)
    {
      // values must be sorted since the SQL will not return an ordered recordset from the two parameters
      if (this.ParamType == "txt")
        optionsArray.sort();
      else
        optionsArray.sort(function(a,b){ return a-b;});

      for(i = 0, j = -1; i < len; i++)
      {
        if(optionsArray[i] != "")
        {
          retArray[++j] = new Object();
          retArray[j].text = optionsArray[i];
          retArray[j].value = optionsArray[i];
        }
      }
    }
    else if (this.TypeMask & LIST2_DISP_PARAM)
    {
      len--;  // decrease length by one since moving through the list 2 at a time
      for(i = 0, j = -1; i < len; i+=2)
      {
        if(optionsArray[i] != "")
        {
          retArray[++j] = new Object();
          retArray[j].text = optionsArray[i];
          retArray[j].value = optionsArray[i + 1];
        }
      }
    }
    else
    {
      for(i = 0, j = -1; i < len; i++)
      {
        if(optionsArray[i] != "")
        {
          retArray[++j] = new Object();
          retArray[j].text = optionsArray[i];
          retArray[j].value = optionsArray[i];
        }
      }
    }
  return retArray;
}

function scListFilter2_SetValue(val)
{
  var isInList = false;
  var len = this.MyList.options.length;
  for(i = 0; i < len; i++)
  {
    if(this.MyList.options[i].value == val)
    {
      this.MyList.options[i].selected = true;
      isInList = true;
      break;
    }
  }
  
  // if not found, need to add it back in
  if(isInList == false)
  {  
    this.MyList.options[len] = new Option(val, val, false, false);
    this.MyList.options[len].selected = true;
  }
}

//------------------------------------------------------------------------
// scTxtFilter
//
// Implements the client side filter handler object associated with a 
// free from text filter
//------------------------------------------------------------------------
function scTxtFilter(id, paramID, paramType, compType, matchExact, minusTolerance, plusTolerance, isTolerancePercent, fltrCtrl, label)
{
  this.Update           = scTxtFilter_Update;
  this.GetValue         = scTxtFilter_GetValue;
  this.SetValue         = scTxtFilter_SetValue;
  this.GetType          = scTxtFilter_GetType;   
  this.GetParamID       = scTxtFilter_GetParamID;    
  this.SetOptions       = scTxtFilter_SetOptions;
  this.Init             = scTxtFilter_Init;
  this.ResetOld         = scTxtFilter_ResetOld;
  this.ResetFilter      = scTxtFilter_ResetFilter;
  this.OnFocus          = scTxtFilter_OnFocus;
  this.OnBlur           = scTxtFilter_OnBlur;  
  this.OnChange         = scTxtFilter_OnChange;
  this.Validate         = scTxtFilter_Validate;
  this.SetFocus         = scTxtFilter_SetFocus;
  this.Blur             = scTxtFilter_Blur;
  
  this.GetFiltParamStr  = scTxtFilter_GetFiltParamsStr;
  this.GetSQLCond       = scFilterBase_GetSQLCond;

  this.ID               = id;         // the ID of this filter control object
  this.ParamID          = paramID;    // the paramater this object is bound to
  this.ParamType        = paramType;  // the paramater type
  this.FilterControl    = fltrCtrl;   // the parent filter control object
  this.MatchExact       = matchExact; // perform partial string matches
  this.CompType         = compType;   // type of comparison
  this.label            = label;      //Label, only used if label is used inside selector
  this.CO               = null;      // remote scripting call object, from SmartCAT 3.6 on remote scripting is no longer employed
  this.MinusTolerance   = minusTolerance;
  this.PlusTolerance    = plusTolerance;
  this.IsTolerancePrct  = Boolean(isTolerancePercent);
  
  this.Min = "~";
  this.Max = "~";
  this.MyText;
   
  this.IsUpdating = false;
  this.OldValue;
  
  this.FilterControl.AddFilter(this); // self register
}

function scTxtFilter_Update()
{

    if (this.label == this.MyText.value)
       this.OldValue = "";
    else
       this.OldValue = this.MyText.value;
           
  if(this.ParamType != "txt")
    this.IsUpdating = true;
  else
    this.IsUpdating = false;
  
  return true;
}

function scTxtFilter_GetType()
{
  return 'txt';
}

function scTxtFilter_Init(initialCond, isIC)
{ 
  this.OldValue = "";

  // grab an internal pointer to the text object
  this.MyText = eval("document." + this.FilterControl.FormID + ".flt" + this.ID);
  
  if(isIC == true)
  {
      if (this.label){
        this.SetValue(this.label);
      }
      else{
        this.SetValue(initialCond);
      }
      
  }
  else
  {
      if (this.label){
        this.MyText.value = this.label;
      }
      else{
        this.MyText.value = "";
      }
  
    if(this.ParamType != "txt")
      this.IsUpdating = true;
    else
      this.IsUpdating = false;
  }
}

function scTxtFilter_GetFiltParamsStr()
{
  var objFilter;
  var strSQLCond = "";
  
  var len = this.FilterControl.FilterList.length;
  for(var i = 0; i < len; i ++)
  { 
    objFilter = this.FilterControl.FilterList[i];
    if(objFilter != this)
      strSQLCond = strSQLCond + objFilter.GetSQLCond();
  }
  return this.ID + "^txt^" + this.ParamID + "^^" + strSQLCond;
}

function scTxtFilter_GetValue()
{

  if (this.label){
    if (this.label == this.MyText.value)
       return ""
    else
       return this.MyText.value;
  }
  else{
    return this.MyText.value;
  }
}

function scTxtFilter_GetParamID()
{
  return this.ParamID;
}

function scTxtFilter_SetValue(val)
{
  this.MyText.value = val;
}

function scTxtFilter_ResetOld()
{
  if (this.label)
    this.MyText.value = this.label;
  else
    this.MyText.value = this.OldValue;
}

// sets the min max values
function scTxtFilter_SetOptions(co)
{
  // split the result string into an array
//  var arrMinMax = co.return_value.split("|");
  var arrMinMax;
  // delete the old entries
  this.Min = "~"
  this.Max = "~"
  
  // set new entries if they exist
  if (co != null)
  {
    arrMinMax = co.split("|");

    if(arrMinMax[0])
      this.Min = parseFloat(arrMinMax[0]);
      
    if(arrMinMax[1])
      this.Max = parseFloat(arrMinMax[1]);
  }      

  this.IsUpdating = false;
}

function scTxtFilter_ResetFilter()
{

  this.OldValue = ""
  
  if (this.label){
    this.MyText.value = this.label;
  }
  else {
      if(this.MyText)
        this.MyText.value = "";  
  }
      
  this.IsUpdating = true
}

function scTxtFilter_OnFocus()
{

  if (this.label){
      if (this.label == this.MyText.value)
         this.MyText.value = "";
  }
         
  this.FilterControl.FocusTarget = this;
  if(this.FilterControl.IsUpdating == true)
    this.MyText.blur();
}

function scTxtFilter_OnBlur()
{
  if (this.MyText.value == "")
     this.MyText.value = this.label;
}

function scTxtFilter_OnChange()
{
  this.FilterControl.UpdateAll();
}

function scTxtFilter_Validate()
{
  //validate the filter before calling the update
  var val = this.GetValue();
  var pType = this.GetType();
  if(pType != "txt" && val != "")
  {
    if(isNaN(val))//parseFloat(val)))
    {
      alert("Numeric input required3");
      this.SetFocus();
      return false;
    }
        
    if(!isNaN(this.Max) && !isNaN(this.Min))
    {
      switch (this.CompType)
      {
        case ">=":
          if (parseFloat(val) > this.Max)
          {
            alert("Please enter a value less than or equal to " + this.Max + ".");
            this.SetFocus();
            return false;
          }
          break;
        case ">":
          if (parseFloat(val) >= this.Max)
          {
            alert("Please enter a value less than " + this.Max + ".");
            this.SetFocus();
            return false;
          }
          break;
        case "<=":
          if (parseFloat(val) < this.Min)
          {
            alert("Please enter a value greater than or equal to " + this.Min + ".");
            this.SetFocus();
            return false;
          }
          break;
        case "<":
          if (parseFloat(val) <= this.Min)
          {
            alert("Please enter a value greater than " + this.Min + ".");
            this.SetFocus();
            return false;
          }
      }
    }
    else
    {
      if (LoadList_Polling_ID == null)
      {
        alert("No available items/parts meet entered criteria.");
        this.ResetOld();
        return false;
      }
    }
  }
  
  return true;
}

function scTxtFilter_SetFocus()
{
  this.MyText.focus();
}

function scTxtFilter_Blur()
{
  this.MyText.blur();
}

//------------------------------------------------------------------------
// scHidFilter
//
// Implements the client side filter handler object associated with a 
// hidden input field
//------------------------------------------------------------------------
function scHidFilter(id, paramID, paramType, compType, matchExact, minusTolerance, plusTolerance, isTolerancePercent, fltrCtrl)
{
  this.Update           = scHidFilter_Update;
  this.GetType          = scHidFilter_GetType;  
  this.GetValue         = scHidFilter_GetValue;
  this.SetValue         = scHidFilter_SetValue;
  this.GetParamID       = scHidFilter_GetParamID;  
  this.SetOptions       = scHidFilter_SetOptions;
  this.Init             = scHidFilter_Init;
  this.ResetOld         = scHidFilter_ResetOld;
  this.ResetFilter      = scHidFilter_ResetFilter;
  this.OnFocus          = scHidFilter_OnFocus;
  this.OnChange         = scHidFilter_OnChange;
  this.Validate         = scHidFilter_Validate;
  this.SetFocus         = scHidFilter_SetFocus;
  this.Blur             = scHidFilter_Blur;
  
  this.GetFiltParamStr  = scHidFilter_GetFiltParamsStr;
  this.GetSQLCond       = scFilterBase_GetSQLCond;

  this.ID               = id;         // the ID of this filter control object
  this.ParamID          = paramID;    // the paramater this object is bound to
  this.ParamType        = paramType;  // the paramater type
  this.FilterControl    = fltrCtrl;   // the parent filter control object
  this.MatchExact       = matchExact; // perform partial string matches
  this.CompType         = compType;   // type of comparison
  this.CO               = null;      // remote scripting call object, from SmartCAT 3.6 on remote scripting is no longer employed
  this.MinusTolerance   = minusTolerance;
  this.PlusTolerance    = plusTolerance;
  this.IsTolerancePrct  = Boolean(isTolerancePercent);
  
  this.Min = "~";
  this.Max = "~";
  this.MyText;
   
  this.IsUpdating = false;
  this.OldValue;
  
  this.FilterControl.AddFilter(this); // self register
}

function scHidFilter_Update()
{
  this.OldValue = this.MyText.value;
  
  if(this.ParamType != "txt")
    this.IsUpdating = true;
  else
    this.IsUpdating = false;
  
  return true;
}

function scHidFilter_GetType()
{
  return 'hid';
}

function scHidFilter_Init(initialCond, isIC)
{ 
  this.OldValue = "";

  // grab an internal pointer to the text object
  this.MyText = eval("document." + this.FilterControl.FormID + ".flt" + this.ID);
  
  if(isIC == true)
  {
    this.SetValue(initialCond);
  }
  else
  {
    this.MyText.value = "";
  
    if(this.ParamType != "txt")
      this.IsUpdating = true;
    else
      this.IsUpdating = false;
  }
}

function scHidFilter_GetFiltParamsStr()
{
  var objFilter;
  var strSQLCond = "";
  
  var len = this.FilterControl.FilterList.length;
  for(var i = 0; i < len; i ++)
  { 
    objFilter = this.FilterControl.FilterList[i];
    if(objFilter != this)
      strSQLCond = strSQLCond + objFilter.GetSQLCond();
  }

  return this.ID + "^txt^" + this.ParamID + "^^" + strSQLCond;
}

function scHidFilter_GetValue()
{
  return this.MyText.value;
}

function scHidFilter_GetParamID()
{
  return this.ParamID;
}

function scHidFilter_SetValue(val)
{
  this.MyText.value = val;
}

function scHidFilter_ResetOld()
{
  this.MyText.value = this.OldValue;
}

// sets the min max values
function scHidFilter_SetOptions(co)
{
  // split the result string into an array
//  var arrMinMax = co.return_value.split("|");
  var arrMinMax;
  // delete the old entries
  this.Min = "~"
  this.Max = "~"
  
  // set new entries if they exist
  if (co != null)
  {
    arrMinMax = co.split("|");

    if(arrMinMax[0])
      this.Min = parseFloat(arrMinMax[0]);
      
    if(arrMinMax[1])
      this.Max = parseFloat(arrMinMax[1]);
  }      

  this.IsUpdating = false;
}

function scHidFilter_ResetFilter()
{
  this.OldValue = this.GetValue()
  this.MyText.value = this.GetValue();
    
  this.IsUpdating = true
}

function scHidFilter_OnFocus()
{
  this.FilterControl.FocusTarget = this;
  if(this.FilterControl.IsUpdating == true)
    this.MyText.blur();
}

function scHidFilter_OnChange()
{
  this.FilterControl.UpdateAll();
}

function scHidFilter_Validate()
{
  //User can't set value so we will have to assume it's valid
  return true;
}

function scHidFilter_SetFocus()
{

}

function scHidFilter_Blur()
{
  this.MyText.blur();
}
//------------------------------------------------------------------------
// scRngFilter
//
// Implements the client side filter handler object associated with a 
// free form range filter
//------------------------------------------------------------------------
function scRngFilter(id, minParamID, maxParamID, minCompType, maxCompType, minusTolerance, plusTolerance, isTolerancePercent, fltrCtrl, label)
{
  this.Update           = scRngFilter_Update;
  this.GetValue         = scRngFilter_GetValue;
  this.SetValue         = scRngFilter_SetValue;
  this.GetType          = scRngFilter_GetType;    
  this.SetOptions       = scRngFilter_SetOptions;
  this.Init             = scRngFilter_Init;
  this.ResetOld         = scRngFilter_ResetOld;
  this.ResetFilter      = scRngFilter_ResetFilter;
  this.OnFocus          = scRngFilter_OnFocus;
  this.OnBlur           = scTxtFilter_OnBlur;  
  this.OnChange         = scRngFilter_OnChange;
  this.Validate         = scRngFilter_Validate;
  this.SetFocus         = scRngFilter_SetFocus;
  this.Blur             = scRngFilter_Blur;

  this.GetFiltParamStr  = scRngFilter_GetFiltParamsStr;
  this.GetSQLCond       = scRngFilter_GetSQLCond;

  this.ID               = id;          // the ID of this filter control object
  this.label            = label;      //Label, only used if label is used inside selector
  this.ParamID          = minParamID;
  this.MinParamID       = minParamID;  // the min parameter this object is bound to
  this.MaxParamID       = maxParamID;  // the max parameter this object is bound to
  this.FilterControl    = fltrCtrl;    // the parent filter control object
  this.MinCompType      = minCompType; // type of comparison against min field (inclusive or not)
  this.MaxCompType      = maxCompType; // type of comparison against max field (inclusive or not)
  this.CO               = null;        // remote scripting call object, from server version 3.6 on remote scripting is no longer used
  this.MinusTolerance   = minusTolerance;
  this.PlusTolerance    = plusTolerance;
  this.IsTolerancePrct  = Boolean(isTolerancePercent);
  
  this.Min = "~";
  this.Max = "~";
  this.MyText;
   
  this.IsUpdating = false;
  this.OldValue;
  
  this.FilterControl.AddFilter(this); // self register
}

function scRngFilter_Update()
{
    if (this.label == this.MyText.value)
       this.OldValue = "";
    else
       this.OldValue = this.MyText.value;
       
  this.IsUpdating = true;
  return true;
}

function scRngFilter_GetType()
{
  return 'rng';
}

function scRngFilter_Init(initialCond, isIC)
{ 
  this.OldValue = "";

  // grab an internal pointer to the text object
  this.MyText = eval("document." + this.FilterControl.FormID + ".flt" + this.ID);
  
  if(isIC == true)
  {
      if (this.label){
        this.SetValue(this.label);
      }
      else{
        this.SetValue(initialCond);
      }
  }
  else
  {
      if (this.label){
        this.MyText.value = this.label;
      }
      else{
        this.MyText.value = "";
      }
    this.IsUpdating = true;
  }
}

function scRngFilter_GetFiltParamsStr()
{
  var objFilter;
  var strSQLCond = "";
  
  var len = this.FilterControl.FilterList.length;
  for(var i = 0; i < len; i ++)
  { 
    objFilter = this.FilterControl.FilterList[i]
    if(objFilter != this)
      strSQLCond = strSQLCond + objFilter.GetSQLCond();
  }

  return this.ID + "^rng^" + this.MinParamID + "^" + this.MaxParamID + "^" + strSQLCond;
}

function scRngFilter_GetValue()
{
  if (this.label){
    if (this.label == this.MyText.value)
       return ""
    else
       return this.MyText.value;
  }
  else{
    return this.MyText.value;
  }
}

function scRngFilter_SetValue(val)
{
  this.MyText.value = val;
}

function scRngFilter_ResetOld()
{
  if (this.label)
    this.MyText.value = this.label;
  else
    this.MyText.value = this.OldValue;
}

// sets the min max values
function scRngFilter_SetOptions(co)
{
  // split the result string into an array
  var arrMinMax;
  // delete the old entries
  this.Min = "~"
  this.Max = "~"

  // set the new ones if they exist
  if (co != null)
  {
    arrMinMax = co.split("|");
  
    if(arrMinMax[0])
      this.Min = parseFloat(arrMinMax[0]);
      
    if(arrMinMax[1])
      this.Max = parseFloat(arrMinMax[1]);
  }

  this.IsUpdating = false;
}

function scRngFilter_ResetFilter()
{
  this.OldValue = ""

  if (this.label){
    this.MyText.value = this.label;
  }
  else {
      if(this.MyText)
        this.MyText.value = "";  
  }

  this.IsUpdating = true
}

function scRngFilter_OnFocus()
{
  if (this.label){
      if (this.label == this.MyText.value)
         this.MyText.value = "";
  }
  
  this.FilterControl.FocusTarget = this;
  if(this.FilterControl.IsUpdating == true)
    this.MyText.blur();
}

function scRngFilter_OnBlur()
{
  if (this.MyText.value == "")
     this.MyText.value = this.label;
}
function scRngFilter_OnChange()
{
  this.FilterControl.UpdateAll();
}

function scRngFilter_Validate()
{
  //validate the filter before calling the update
  var val = this.GetValue();
  if(val != "")
  {
    if(isNaN(val))//parseFloat(val)))
    {
      alert("Numeric input required");
      return false;
    }
        
    if(!isNaN(this.Max) && !isNaN(this.Min))
    {
      if (this.Max == this.Min && parseFloat(val) != this.Min)
      {
        alert("Please enter " + this.Min);
        return false;
      }
      switch (this.MinCompType)
      {
        case "<=" :
          if (this.MaxCompType == ">=")
          {
            // inclusive at both min and max
            if (parseFloat(val) > this.Max ||
                parseFloat(val) < this.Min)
            {
              alert("Please enter a value greater than or equal to " +
                     this.Min + " and less than or equal to " + this.Max);
              return false;
            }
          }
          else
          {
            // inclusive at min and exclusive at max
            if (parseFloat(val) >= this.Max ||
                parseFloat(val) <  this.Min)
            {
              alert("Please enter a value greater than or equal to " +
                     this.Min + " and less than " + this.Max);
              return false;
            }
          }
          break;
        case "<"  :
          if (this.MaxCompType == ">=")
          {
            // exclusive at min and inclusive at max
            if (parseFloat(val) >  this.Max ||
                parseFloat(val) <= this.Min)
            {
              alert("Please enter a value greater than " +
                     this.Min + " and less than or equal to " + this.Max);
              return false;
            }
          }
          else
          {
            // exclusive at both min and max
            if (parseFloat(val) >= this.Max ||
                parseFloat(val) <= this.Min)
            {
              alert("Please enter a value greater than " +
                     this.Min + " and less than " + this.Max);
              return false
            }
          }
          break;
      } // end of switch (this.MinCompType)
    } // end of if(!isNaN(this.Max) && !isNaN(this.Min))
    else
    {
      alert("No available items/parts meet entered criteria.");
      this.ResetOld();
      return false;
    }
  } // end of if(val != "")
  
  return true;
}

function scRngFilter_SetFocus()
{
  this.MyText.focus();
}

function scRngFilter_Blur()
{
  this.MyText.blur();
}

function scFilterBase_GetSQLCond()
{

  var strSQLCond = "";
  //var strQuot;
  var strVal;
  var val;
  var isValid = false;
   
  strVal = this.GetValue()
  
  if (strVal != "")
    strVal = strVal.replace(/\'/gi, "''")
  
  if(this.ParamType == "txt")
  {
    //strQuot = "'";
    val = strVal;
    if(val != "")
      isValid = true;
  }
  else
  {
    //strQuot = "";
    val = parseFloat(strVal.replace(/,/gi, ""), 10);
    if(strVal != "" && !isNaN(val))
      isValid = true;
    // if the min or max on an input filter is undefined, then ignor whatever the user entered
    if (this.Min || this.Max)
      if ((this.Min == "~" || this.Max == "~") && LoadList_Polling_ID == null)
        isValid = false;
  }
    
  if(isValid == true)
  {       
    strSQLCond += "param" + this.ParamID;


            
    if (this.ParamID == 99999)
    {
        strSQLCond = strSQLCond.replace("param99999","")
        var oRequest = new XMLHttpRequest();
        var sURL  = "http://"+self.location.hostname+"/sc_app/st_current_customer.asp";
        oRequest.open("GET",sURL,false);
        oRequest.setRequestHeader("User-Agent",navigator.userAgent);
        oRequest.send(null)
        var cust = oRequest.responseText;
        strSQLCond += " param64 IN (SELECT emhart_part_no" + 
                      " FROM st_customer_groups_lkup INNER JOIN  st_customer_parts_lkup ON st_customer_groups_lkup.customer_id = st_customer_parts_lkup.customer_id" +
                      " WHERE st_customer_groups_lkup.customer_name  ='" + cust + "' AND  st_customer_parts_lkup.customer_part_no LIKE N'%" + strVal + "%') ";;

    }
    else if(this.MatchExact != "Yes" && this.ParamType == "txt")
    {
      // partial string match, wrap with wildcards
      // only valid for txt types
      strSQLCond += " LIKE N'%" + strVal + "%'";
    }
    else
    {
      if (this.MinusTolerance == 0 && this.PlusTolerance == 0)
      {
        // conditional comparison
        if(this.ParamType == "txt")
          strSQLCond += this.CompType + "N'" + val + "'";
        else
          strSQLCond += this.CompType + val;
      }
      else
      {
        if (this.IsTolerancePrct == true)
        {
          // Build Min param check
          strSQLCond += ">=" + (val - (val * this.MinusTolerance)) + " AND ";
          // Build Max param check
          strSQLCond += "param" + this.ParamID + "<=" + (val + (val * this.PlusTolerance));
        }
        else
        {
          // Build Min param check
          strSQLCond += ">=" + (val - this.MinusTolerance) + " AND ";
          // Build Max param check
          strSQLCond += "param" + this.ParamID + "<=" + (val + this.PlusTolerance);
        }
      }
    }
    g_SQL_symbols.Insert("p" + this.ParamID, strSQLCond)
    strSQLCond += " AND ";
    strSQLCond = "p" + this.ParamID + " AND "
  }
  
  return strSQLCond;
}

function scFilterBase2_GetSQLCond()
{
  var strSQLCond = "";
  //var strQuot;
  var strVal;
  var val;
  var isValid = false;
   
  strVal = this.GetValue()
  if (strVal != "")
    strVal = strVal.replace(/\'/gi, "''")
    
  if(this.ParamType == "txt")
  {
    //strQuot = "'";
    val = strVal;
    if(val != "")
    {
      g_SQL_symbols.Insert("p" + this.MinValParamID,"param" + this.MinValParamID + "='" + val + "'")
      strSQLCond += " param" + this.MinValParamID + "=N'" + val + "' AND ";
      strSQLCond = " p" + this.MinValParamID + " AND"
    }
  }
  else
  {
    //strQuot = "";
    val = parseFloat(strVal, 10);
    if(strVal != "" && !isNaN(val))
      isValid = true;
  }
    
  if(isValid == true && this.ParamType != "txt")
  {       
    if (this.TypeMask & LIST2_MIN_MAX_VAL_PARAM) // dealing with two parameters (a range)
    {
      if (this.MinusTolerance != 0 && this.PlusTolerance != 0) // a tolerance is associated with the value
      {
        if (this.TypeMask & LIST2_TOLERANCE_PERCENT) // tolerance is percentage
          strSQLCond += " param" + this.MinValParamID + this.MinCompType + (val * (1 - this.MinusTolerance)) +
                        " AND param" + this.MaxValParamID + this.MaxCompType + (val * (1 + this.PlusTolerance))
        else // tolerance is not a percentage (straight up values)
          strSQLCond += " param" + this.MinValParamID + this.MinCompType + (val - this.MinusTolerance) +
                        " AND param" + this.MaxValParamID + this.MaxCompType + (val + this.PlusTolerance)
      }
      else // no tolerance associated with value
      {
        strSQLCond += " param" + this.MinValParamID + this.MinCompType + val +
                      " AND param" + this.MaxValParamID + this.MaxCompType + val
      }
    }
    else // not dealing with range of values
    {
      if (this.MinusTolerance != 0 && this.PlusTolerance != 0) // tolerance is associated with the value
      {
        if (this.TypeMask & LIST2_TOLERANCE_PERCENT)
          strSQLCond += " param" + this.MinValParamID + " >= " + (val * (1 - this.MinusTolerance)) +
                        " AND param"+ this.MinValParamID + " <= " + (val * (1 + this.PlusTolerance))
        else
          strSQLCond += " param" + this.MinValParamID + " >= " + (val - this.MinusTolerance) +
                        " AND param"+ this.MinValParamID + " <= " + (val + this.PlusTolerance)
      }
      else
      {
        strSQLCond += " param" + this.MinValParamID + this.CompType + val
      }
    }
    g_SQL_symbols.Insert("p" + this.MinValParamID, strSQLCond)
    strSQLCond += " AND ";
    strSQLCond = " p" + this.MinValParamID + " AND "
  }
  
//  alert(strSQLCond);
  return strSQLCond;
}

function scRngFilter_GetSQLCond()
{
  var strSQLCond = "";
  var strVal;
  var val;
  var isValid = false;
   
  strVal = this.GetValue()
  if (strVal != "")
    strVal = strVal.replace(/\'/gi, "''")
    
  val = parseFloat(strVal, 10);
  if(strVal != "" && !isNaN(val))
    isValid = true;
    
  if(isValid == true)
  {       
    if (this.MinusTolerance == 0 && this.PlusTolerance == 0)
    {
      // Build Min param check
      strSQLCond += "param" + this.MinParamID + this.MinCompType + val;
      // Add on Max param check
      strSQLCond += " AND param" + this.MaxParamID + this.MaxCompType + val;
    }
    else
    {
      if (this.IsTolerancePrct == true)
      {
        // Build Min param check
        strSQLCond += "param" + this.MinParamID + this.MinCompType + (val - (val * this.MinusTolerance));
        // Build Max param check
        strSQLCond += " AND param" + this.MaxParamID + this.MaxCompType + (val + (val * this.PlusTolerance));
      }
      else
      {
        // Build Min param check
        strSQLCond += "param" + this.MinParamID + this.MinCompType + (val - this.MinusTolerance);
        // Build Max param check
        strSQLCond += " AND param" + this.MaxParamID + this.MaxCompType + (val + this.PlusTolerance);
      }
    }
    g_SQL_symbols.Insert("p" + this.MinParamID, strSQLCond)
    strSQLCond += " AND ";
    strSQLCond = "p" + this.ParamID + " AND "
  }
  
  return strSQLCond;
}

//------------------------------------------------------------------------
// scCheckEnter
//
// IE will not generate an onchange event for a text box by pressing the
// enter key unless there is a submit button on the form. We register this
// method to handle window.keyPress events for Selector document (see 
// scFilterInit and use it to test for the enter key being pressed.
//------------------------------------------------------------------------
function scCheckEnter(evt)
{
  if(IsIE4 == true)
  {
    if(window.event.keyCode == KEY_ENTER)
    {
      var id = parseInt(window.event.srcElement.id.substr(3)); 
      theFilter.RotateFocus(id);
      
      return false; // stop processing this event
    }
  }
  else
  {
    if(evt.which == KEY_ENTER)
    {
      var id = parseInt(evt.target.name.substr(3));
      theFilter.RotateFocus(id);
      return false;
    }
    else
    {
      routeEvent(evt); // don't stop processing
    }
  }
}

function showErrors(co)
{
  // Dump raw data
  msg = "The raw data returned by the remote method call is \n"
  msg = msg + co.data    
  alert(msg); 
  /*

  // Display friendlier information
  msg = "The following error occurred during the "
  msg = msg + co.context
  msg = msg + " remote scripting call:\n"
  msg = msg + co.message   
  alert(msg)
*/  
  
//  msg =  "An error has occured loading this page.\n" 
//  msg += "Please try to reload the page using your browser's refresh button";
  
  
//  alert(msg);
}

//------------------------------------------------------------------------
// scNavSwitchTo
//
// Switches the current page to the node in the NavControl selection
// list
//------------------------------------------------------------------------
function scNavSwitchTo(theNavCtrl)
{
  
  // clear the selection state
  var frmMenu = sc_FindFrame("sc_header");
  if(frmMenu)
    frmMenu.strSelectionState = "";
    
  var strAction;
  if(theNavCtrl)
    strAction = theNavCtrl.options[theNavCtrl.selectedIndex].value;
  
  eval(strAction);
}

function scNavOpenTOCTo(famID)
{
  sc_OpenLocation("sc_tocframe.asp?OpenTo=" + famID + "&vid=" + view_code, "sc_main");
}

function scSaveSelState()
{  
  // set the save selection state flag
  var frmMenu = sc_FindFrame("sc_header");
  if(frmMenu)
    frmMenu.IsSaveSelState = true;

}

//=============================================
//A new standard customizePart action function
//=============================================
function scCustomizePart(famID, viewID, prtNo, strUOM)
{
	var frmMenu = sc_FindFrame("sc_header");
  var frmMain = sc_FindFrame("sc_main");
  var frmSel = sc_FindFrame("sc_prod_sel");
  var frmSrc = sc_FindFrame("c_srchtbl");
  
  if(frmMenu && frmSel)
  {               //selector page
		frmSel.theFilter.SaveState();
		frmMenu.IsSaveSelState = true;
		frmMenu.MainLoc = "../sc_app/sc_selframe.asp?famID=" + frmSel.theFilter.FamID + "&UOM=" + frmSel.theFilter.strUOM + "&vid=" + viewID;
  }
  else
		if (frmSrc)  //part search 
			frmMenu.MainLoc = "c_srchframe.asp?vid=" + viewID;
		else				 //spec page
			frmMenu.MainLoc = "../sc_app/sc_specsheet.asp?famID=" + famID + "&UOM=" + strUOM + "&prtNo=" + encodeURI(prtNo) + "&vid=" + viewID;

	var strURL = "sc_custprt_main.asp?" +
							 "famID="   + famID  +
							 "&strUOM=" + encodeURI(strUOM) +
							 "&prtNo="  + encodeURI(prtNo)  +
							 "&vid="    + encodeURI(viewID);
	
   /*var strURL = "../../default.asp?pageType=customize" +
                    "&famID=" + famID +
                    "&prtNo=" + encodeURI(prtNo) +
                    "&strUOM=" + encodeURI(strUOM) +
                    "&vid=" + encodeURI(viewID)    */                
  sc_OpenLocation(strURL, "sc_main");	

}
