/*!
* Copyright 2008 to the present, Adtec Digital. All rights reserved.
*//******************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file contains different functions and utilities that serve common purposes
 *              for the Web User interface, and external components (e.g modCalculator).
 *****************************************************************************/
  
var 
/****************************************************************************************************
 *                                       Global Constants
 *
 * NOTE:  const Keyword is not supported by Internet Explorer. Thus var is used instead, even 
 * though they refer to constants.  Treat these variables as #define's (in C/C++ code terms) 
 * and (even though its possible)  DO NOT re-assign them at run time.                                            
****************************************************************************************************/
_DOMFIELDSTATE = 
   {
   "ENABLED":              false,
   "DISABLED":             true
   },

_MODTYPE = 
   {
   "DVB_DSNG": -1, //not supported
   "NTC": 0, //not supported
   "SKYPLEX_SCPC": 1, //not supported
   "DVB_S": 3,
   "DVB_S2": 5
      }, 
  
   _NA =                            "N/A",
 
   
_DEFAULT_LOGARITHM_BASE = 10,

_LBM_DVBS2_VAL = 5,

//YUI shortcuts
_yuiUtil = YAHOO.util,
_yuiStringify = YAHOO.lang.JSON.stringify, //shortcut to JsonStringify function 
_yuiParseJson = YAHOO.lang.JSON.parse, //shortcut to JsonStringify function
_yuiDom = _yuiUtil.Dom, //shortcut to YUI representation of DOM
_yuiEvent = _yuiUtil.Event, //shortcut to YUI event
_yuiCustomEvent = _yuiUtil.CustomEvent, //shortcut to custom event
_yuiConnect = _yuiUtil.Connect, //shortcut to YUI Connection manager object,
_yuiDs = _yuiUtil.DataSource,  //Shortcut to YUI Datasource singleton,
_yuiDt = YAHOO.widget.DataTable,  //Shortcut to YUI Datatable singleton,
$ = _yuiDom.get, //shortcut to document.getElementById 

//COLORS:
_ADTCOLOR = 
   {
   "BLACK":          "#000000",
   "GREY":           "#777777",
   "WHITE":          "#FFFFFF",
   "RED":            "#FF0000",
   "GREEN":          "#339900", 
   "BLUE":           "#0000FF",
   "YELLOW":         "#CC9933",
   "SILVER":         "#C0C0C0",
   "LIGHTGREY":      "#F4F4F4",
   "GOLD":           "#CC9933",  
   "DEFAULT":        ""
   },
   
//unit conversion helpers
_TEN =            10,
_HUNDRED =        (_TEN * _TEN),
_THOUSAND =       (_HUNDRED * _TEN),
_MILLION =        (_THOUSAND * _THOUSAND),
_DEFAULT_INFO_MSG_TIMEOUT  = 3000,
_DEFAULT_CURSOR_WAIT_TIMEOUT  = 2000
   ;
   
   


var 
/*************************************************************
 * Returns the logarithm of the given value w/ the given base.
 * If no base is entered, 10 is assumed.
 **************************************************************/
GetLogarithm = function 
    (
    val, 
    base //optional.  10 by default
    )
    {
    if(base===undefined || base===null || base===0){base = _DEFAULT_LOGARITHM_BASE;}
    return Math.log(val) / Math.log(base);
    },
    
/*************************************************************
  * Returns the logarithm base 10 of the given value.
*************************************************************/
GetLogarithm10 = function  (val)
    {
    return GetLogarithm(val, 10);
    },
    
/*************************************************************
 * Adjusts DOM to change the color of the given element.  
 * If no color is entered, BLACK is assumed.
 ************************************************************/
DomSetElementColor = function
    (
    el,
    color
    )
    {
    if(el===null || el===undefined)
       {
       LogMyles("Set Element Color aborted. Parameter is null");
       return;
       }
    if((color===undefined)||(color===null))
       {
       color = _ADTCOLOR.BLACK;
       }
    el.style.color = color;
    }
    ;
  /*****************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file contains all the global definitions for the  Web User interface, 
 *****************************************************************************/
var 
   
_ADTEC_FEATURE_EXT = "asc",
_ADTEC_DVC_EXT = "dvc",
_AUDIO_NUM_SDI_CHANNELS = 16,
_APPLY_IMG_PATH = "/images/apply.gif",
_CANCEL_IMG_PATH = "/images/cancel.gif",
_CMDHLIST = ["SYSD", "DCMD", "ECMD", "ECMD0", "ECMD1", "MCMD", "DPID", "CMDD"],
_DT_HDR_TR_CLASS = "dtHdrTrClassId",
_DCDRTHUMBNAIL_ID =  "dcdrThumbnailId",
_DCDR_CANVAS_HEIGHT=100,
_DCDR_CANVAS_LINE_WIDTH = 1,
_DCDR_CANVAS_PREFIX =  "dcdrAudioCanvas",
_DCDR_CANVAS_NUM_AUDIOS = 16,
_DCDR_CANVAS_AUDIO_WIDTH = 11,
_DCDR_CANVAS_AUDIO_DELIM_WIDTH = 1,
_DCDR_CANVAS_WIDTH = (_DCDR_CANVAS_NUM_AUDIOS*_DCDR_CANVAS_AUDIO_WIDTH)+((_DCDR_CANVAS_NUM_AUDIOS-1)*_DCDR_CANVAS_AUDIO_DELIM_WIDTH), 
_DCDRTHUMBNAIL_SRC = "/dcdrThumbnail",
_ELA_100LAT_VAL = 4,
_EN_NUM_INPUTS_WOUT_FEAK = 4,
_ENC_ALV_MIN_VAL = -18,
_ENC_ALV_MAX_VAL = 8,
_JSON_IMG_EXPANDED =  "/images/jsonPlus.gif",
_JSON_IMG_COLLAPSED = "/images/jsonMinus.gif",
_LN10 = Math.log(10),
_MAX_RD_GEN_PIX_PHASE = 63,
_MAX_VBI_LINE_NUMBER =        22,
_MIN_HD_VSIZE = 720,
_MIN_HD_HSIZE = 1280,
_MIN_NT_SW_VR_FOR_RF_GAIN_SUPPORT = 1.19,
_MIN_KU_VALUE =         8000, 
_MIN_VBI_LINE_NUMBER =        7,
_MIN_SDI_TLTXT_LINE_NUMBER = 7,
_MAX_SDI_TLTXT_LINE_NUMBER = 18,
_MODALCONTAINERDIV = "modContainerDiv",
_NAV_ITEM_CLASS =       "navigationitem",     //NOTE..  Case sensitive.. Must match definition in myles.css file.
_NAV_LINK_CLASS =       "navigationlink",   //NOTE..  Case sensitive.. Must match definition in myles.css file.
_NEWTEC_DEMOD_REGEX = /NTC\/?(70\d{2})\/?(\wB)?.*/i,
_NUM_EBU_PARADIGMS =    8,
_NUM_MCAST_DESTINATIONS = 4,
_EN_NUM_INPUTS_WOUT_FEAK = 4,
_PAGE_PREFIX =          "pg_",
_PRF_STATUS_CHECK_INTERVAL = 3000,
_STR_VBHTABID =     "vbihTable",
_TAB_PREFIX =           "tb_",
_THUMBNAILCONTAINERDIV = "thumbnailContainerDiv",
_AUDIOTHUMBNAILCONTAINERDIV = "audioThumbnailContainerDiv",
_MIN_TMR = 700000,

_AUDIO_STREAMTYPE_STR_LIST = 
   [
   "MPEG1_Audio",
   "MPEG2_Audio",
   "DVB_AC3_AUDIO",
   "AAC",
   "ISO_IEC_13818_7_AUDIO_ADTS",
   "AAC",
   "DOLBY_AC3"
   ],
_QV1STATUS = 
   {
   "OK":             0,
   "NO_VIDEO":       1,
   "NO_HD_FK":       2
   },
_RDHWCONF = 
   {
   "NO_DEMOD":       0,
   "ADTEC_DEMOD":    1,
   "NEWTEC_DEMOD":   2
   },
   
//ATTENTION.  This enum must be in sync with pStrMapDcdrSdiAudioMatrixSourceArgs on the server side.  If one changes, so, must the other.   
_SMX_STATUS_SRCTYPE = 
   { 
   "AUDIO":          0, 
   "TONEGEN":        1, 
   "PASSTHRU":       2, 
   "MUTE":           3
   },
   
_FECVAL = {"off": 0,      "on":  1,      "maxburst": 2,      "burst": 3,      "lowlatency": 4  },
_MOD_UPLINK_MODE =   {"NORMAL":            1,"INVERTED":          2},

_STREAMTYPE = 
   {
   "UNKNOWN": 0,            
   "ISO_IEC_11172_VIDEO": 1, 
   "ISO_IEC_13818_VIDEO": 2,      
   "ISO_IEC_11172_AUDIO": 3,
   "ISO_IEC_13818_AUDIO": 4,     
   "ISO_IEC_13818_PRIVATE": 5, 
   "DVB_AC3_AUDIO": 6,
   "ISO_IEC_13522_MHEG": 7,      
   "DSM_CC": 8, 
   "ITU_T_REC_H222_1": 9,      
   "ISO_IEC_13818_6_Type_A": 10,
   "ISO_IEC_13818_6_Type_B": 11,      
   "ISO_IEC_13818_6_Type_C": 12, 
   "ISO_IEC_13818_6_Type_D": 13,      
   "ISO_IEC_13818_1_Aux": 14,
   "ISO_IEC_13818_7_AUDIO_AAC": 15,      
   "ISO_IEC_14496_3_AUDIO": 17,      
   "H264_VIDEO": 27,
   "DCII_VIDEO": 128, 
   "AC3_AUDIO": 129,   
   "DCII_SUBTITLES": 130,
   "ADTEC_PMT": 256,      
   "ADTEC_PCR": 257, 
   "ADTEC_TELETEXT": 258,      
   "ADTEC_SUBTITLE": 259,
   "ADTEC_VBIDATA": 260,      
   "ADTEC_VBITELETEXT": 261, 
   "ADTEC_EMM": 262,      
   "ADTEC_ECM": 263,
   "ADTEC_PAT": 264
   },
//TODO Doc
 _PAGEIDX = 
   {
   "adc0": 0,  //  audio channel 0
   "adc1": 1,  //  audio channel 1
   "adc2": 2,  //  audio channel 2
   "adc3": 3,  //  audio channel 3
   "adc4": 4,  //  audio channel 4
   "adc5": 5,  //  audio channel 5
   "adc6": 6,  //  audio channel 6
   "adc7": 7,  //  audio channel 7
   "ast": 8,  //  asiTransport
   "bti": 9,  //  barsTonesID
   "cas": 10,  //  cas
   "ch0": 11, "ch1": 12, "ch2": 13, "ch3": 14, "ch4": 15, "ch5": 16, "ch6": 17, "ch7": 18, "ch8": 19, "ch9": 20, "ch10": 21, "ch11": 22,    
   "cpt": 23,  //  captions
   "ctl": 24,  //  control
   "dec": 25,  //  decoder
   "dem": 26,  //  demodulatorTab
   "dsp": 27, //  display
   "dtv": 28, //  dtvconfig
   "eas": 29, //  eas
   "enc": 30, //  encoder
   "fea": 31, //  features
   "fmw": 32, //  firmware
   "gau": 33, //  global audio
   "hlp": 34, //  help
   "ipp": 35, //  input ip
   "inv": 36, //  inventory
   "ipo": 37, //  IP Out
   "ipt": 38, //  ipTransport
   "lbm": 39, //  L-Band Modulator
   "ntp": 40, //  network
   "ntw": 41, //  nitparameters
   "osd": 42, //  osd
   "pid": 43, //  Pid
   "prf": 44, //  Profile
   "qad": 45, //  Qam Audio
   "qam": 46, //  QAM/RF
   "qen0": 47, // Qam Encoder 1
   "qen1": 48, // Qam Encoder 2
   "qpd": 49, //  QAM Pid
   "qvb0": 50, //  QAM VBI (Captions & Teletext)
   "qvb1": 51, //  QAM VBI (Captions & Teletext)
   "rda": 52, //  RD Audio  
   "rdb": 53, //  rdVbi
   "rdg": 54, //  RD Genlock
   "rdm": 55, //  RD Audio Matrix
   "rdo": 56, //  RD Video Output
   "rds": 57, //  rdServicesTab
   "sch": 58, //  scheduler
   "sec": 59, //  Security
   "str": 60, //  streaming
   "sys": 61, //  System
   "tss": 62, //  TS settings
   "ttx": 63, //  teletext
   "max": 64  //  update accordingly

   },

//TODO Doc
 _PAGE = 
   [ 
   {
   "id":    "adc0",
   "name":  "Audio 1", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc1",
   "name":  "Audio 2", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc2",
   "name":  "Audio 3", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc3",
   "name":  "Audio 4", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc4",
   "name":  "Audio 5", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc5",
   "name":  "Audio 6", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc6",
   "name":  "Audio 7", //audio channel
   "tbd":   null       
   },
   {
   "id":    "adc7",
   "name":  "Audio 8", //audio channel
   "tbd":   null       
   },
   {
   "id":    "ast",
   "name":  "ASI Transport",
   "tbd":   null       
   },
   {
   "id":    "bti",
   "name":  "Bars Tones & ID",
   "tbd":   null       
   },
   {
   "id": "cas",
   "name":  "CAS", //CAS
   "tbd":   null       
   },
   {"id": "ch0", "name":"Channel 1", "tbd":null},
   {"id": "ch1", "name":"Channel 2", "tbd":null},
   {"id": "ch2", "name":"Channel 3", "tbd":null},
   {"id": "ch3", "name":"Channel 4", "tbd":null},
   {"id": "ch4", "name":"Channel 5", "tbd":null},
   {"id": "ch5", "name":"Channel 6", "tbd":null},
   {"id": "ch6", "name":"Channel 7", "tbd":null},
   {"id": "ch7", "name":"Channel 8", "tbd":null},
   {"id": "ch8", "name":"Channel 9", "tbd":null},
   {"id": "ch9", "name":"Channel 10", "tbd":null},
   {"id": "ch10", "name":"Channel 11", "tbd":null},
   {"id": "ch11", "name":"Channel 12", "tbd":null},
   {
   "id":    "cpt",
   "name":  "Captions",
   "tbd":   null
   },
   {
   "id":    "ctl",
   "name":  "Control",
   "tbd":   null
   },
   {
   "id":    "dec",
   "name":  "Decoder",
   "tbd":   null
   },
   {
   "id":    "dem",
   "name":  "RF Params", //Demodulator
   "tbd":   null
   },
   {
   "id":    "dsp",
   "name":  "Display",
   "tbd":   null
   },
   {
   "id":    "dtv",
   "name":  "DTVGuide Config",
   "tbd":    null
   },
   {
   "id": "eas", //  eas
   "name":  "EAS",
   "tbd":   null
   },
   {
   "id":    "enc",
   "name":  "Encoder",
   "tbd":   null
   },
   {
   "id":    "fea",
   "name":  "Features",
   "tbd":   null
   },
   {
   "id":    "fmw",
   "name":  "Firmware",
   "tbd":   null
   },
   
   {
   "id":    "gau",
   "name":  "Global Audio",
   "tbd":   null
   },
   {
   "id": "hlp", //  help
   "name":  "Help",
   "tbd":   null
   },
   {
   "id":    "ipp",
   "name":  "IP Params",
   "tbd":   null
   },
   {
   "id":    "inv",
   "name":  "Inventory",
   "tbd":   null
   },
   {
   "id": "ipo", //  IP Out
   "name":  "IP Out",
   "tbd":   null
   },
   {
   "id":    "ipt",
   "name":  "IP Transport",
   "tbd":   null
   },
   {
   "id": "lbm", //  L-Band Modulator
   "name":  "Modulator",
   "tbd":   null
   },
   {
   "id":    "ntp",
   "name":  "NIT Params",
   "tbd":   null
   },
   {
   "id": "ntw",
   "name":  "Network",
   "tbd":   null
   },
   {
   "id":    "osd",
   "name":  "OSD",
   "tbd":   null
   },
   {
   "id": "pid",
   "name":  "PID",
   "tbd":   null
   },
   {
   "id": "prf",
   "name":  "Profile",
   "tbd":   null
   },
   {
   "id": "qad", //  QAM Audio
   "name":  "Audio",
   "tbd":   null
   },
   {
   "id": "qam", //  QAM/RF
   "name":  "QAM/RF",
   "tbd":   null
   },
   {
   "id": "qen0", //  Qam Encoder 1
   "name":  "Encoder 1",
   "tbd":   null
   },
   {
   "id": "qen1", //  Qam Encoder 2
   "name":  "Encoder 2",
   "tbd":   null
   },
   {
   "id": "qpd", // QAM Pid
   "name": "PID",
   "tbd": null
   },
   {
   "id":    "qvb0",
   "name":  "Encoder 1", //Captions & Teletext
   "tbd":   null
   },
   {
   "id":    "qvb1",
   "name":  "Encoder 2", //Captions & Teletext
   "tbd":   null
   },
   {
   "id": "rda", //  RD Audio
   "name":  "Audio",
   "tbd":   null
   },
   {
   "id":    "rdb",
   "name":  "RD VBI",
   "tbd":   null
   },
   {
   "id":    "rdg",
   "name":  "Genlock",
   "tbd":   null
   },
   {
   "id":    "rdm",
   "name":  "SDI Matrix",
   "tbd":   null
   },
   {
   "id":    "rdo",
   "name":  "Output",
   "tbd":   null
   },
   {
   "id":    "rds",
   "name":  "RD Services",
   "tbd":   null
   },
   {
   "id":    "sch",
   "name":  "Scheduler",
   "tbd":   null
   },
   {
   "id": "sec", //  Security
   "name":  "Security",
   "tbd":   null
   },
   {
   "id":    "str",
   "name":  "Streaming",
   "tbd":   null
   },
   {
   "id": "sys", //  System
   "name":  "System",
   "tbd":   null
   },
   {
   "id":    "tss",
   "name":  "TS Settings", //TS Settings
   "tbd":   null
   },
   {
   "id":    "ttx",
   "name":  "Teletext",
   "tbd":   null
   }
   
    ],
   
//TODO Doc    
 _TABIDX = 
   {
    //common tabs
   "hlp":  0, //Help
   "sys":  1, //System
   "upg":  2, //Upgrade
    
    //product-line specific tabs
   "aud":  3, //Audio
   "cas":  4, //CAs
   "chs":  5, //Channels
   "dsb":  6, //Dashboard
   "dtv":  7, //DTVGuide Config
   "eas":  8, //EAS
   "inp":  9, //input
   "ipo":  10, //IP Output
   "mod":  11, //Modulator
   "ntw":  12, //Network
   "pid":  13, //PID
   "prf":  14, //Profile
   "qam":  15, //QAM/RF
   "qen":  16, //QAM Video
   "qpd":  17, //QAM Pid
   "qvb":  18, //QAM VBI (Captions & Teletext)
   "rda":  19, //RD Audio
   "rdb":  20, //RD VBI
   "rdv":  21, //RD Video
   "sec":  22, //Security
   "svc":  23, //Service
   "svs":  24, //Services
   "std":  25, //Studio
   "vbi":  26, //VBI
   "vid":  27, //Video
   "max":  28 //Max..  update accordingly     
   },
    
//TODO Doc  
_TAB = 
   [
   // common Tabs
   {
   "id": "hlp",
   "name": "Help",
   "subnav": [_PAGEIDX.hlp]
   },
   {
   "id": "sys",
   "name": "System",
   "subnav": [_PAGEIDX.sys]
   },
   {
   "id": "upg",
   "name": "Upgrade",
   "subnav": 
      [
      _PAGEIDX.fmw //firmware  NOTE GE 1/10/2011. Features Page is added dynamically at load-time for those products that support it.
      ]
   },
    
   {
   "id": "aud",
   "name": "Audio",
   "subnav": 
      [
      _PAGEIDX.gau //Global Audio ..  NOTE GE 1/10/2011. Additional audios are added dynamically at load-time.
      ]
   },
   {
   "id": "cas",
   "name": "CAS",
   "subnav": [_PAGEIDX.cas]
   },
   {
   "id": "chs",
   "name": "Channels",
   "subnav":[_PAGEIDX.ch0, _PAGEIDX.ch1,_PAGEIDX.ch2,_PAGEIDX.ch3,_PAGEIDX.ch4,_PAGEIDX.ch5,_PAGEIDX.ch6,_PAGEIDX.ch7,_PAGEIDX.ch8,_PAGEIDX.ch9,_PAGEIDX.ch10,_PAGEIDX.ch11]
   },
   {
   "id": "dsb",
   "name": "Dashboard",
   "subnav": 
      [
      _PAGEIDX.inv, //inventory
      _PAGEIDX.sch, //scheduler
      _PAGEIDX.str, //streaming
      _PAGEIDX.dsp, //display
      _PAGEIDX.osd //osd
      ]
   },
   {
   "id": "dtv",
   "name": "DTVGuide Config",
   "subnav": [_PAGEIDX.dtv]
   },
   {
   "id": "eas",
   "name": "EAS",
   "subnav": [_PAGEIDX.eas]
   },
   {
   "id": "inp",
   "name": "Input",
   "subnav": 
      [
      _PAGEIDX.rds, //RD Services
//      _PAGEIDX.dem, //RF Params / Demodulator NOTE GE 1/10/2011. Demod is inserted only after hardware has been verified. This happens at load-time.
      _PAGEIDX.ipp, //Input ip
      _PAGEIDX.bti //Bars Tones & ID
      ]
   },
   {
   "id": "ipo",
   "name": "IP Out",
   "subnav": [_PAGEIDX.ipo]
   },
   {
   "id": "mod",
   "name": "Modulator",
   "subnav":  [_PAGEIDX.lbm] 
   },
   {
   "id": "ntw",
   "name": "Network",
   "subnav": [_PAGEIDX.ntw]
   },
   {
   "id": "pid",
   "name": "PID",
   "subnav": [_PAGEIDX.pid]
   },
   {
   "id": "prf",
   "name": "Profile",
   "subnav": [_PAGEIDX.prf]
   },
   {
   "id": "qam",
   "name": "Modulator",
   "subnav": [_PAGEIDX.qam]
   },
   {
   "id": "qen",
   "name": "Video",
   "subnav": [_PAGEIDX.qen0, _PAGEIDX.qen1]
   },
   {
   "id": "qpd",
   "name": "PID",
   "subnav": [_PAGEIDX.qpd]
   },
   {
   "id": "qvb",
   "name": "VBI",
   "subnav": [_PAGEIDX.qvb0, _PAGEIDX.qvb1]
   },
   {
   "id": "rda",
   "name": "Audio", //!< RD Audio
   "subnav": [_PAGEIDX.rda, _PAGEIDX.rdm]
   },
   {
   "id": "rdb",
   "name": "VBI", //!< RD VBI
   "subnav": [_PAGEIDX.rdb]
   },
   {
   "id": "rdv",
   "name": "Video", //!< RD Video
   "subnav": [_PAGEIDX.rdg, _PAGEIDX.rdo]
   },
   {
   "id": "sec",
   "name": "Security",
   "subnav": [_PAGEIDX.sec]
   },
   {
   "id": "svc",
   "name": "Service",
   "subnav": 
      [
      _PAGEIDX.ast, //ASI transport
      _PAGEIDX.ipt, //IP transport
      _PAGEIDX.bti //BARS Tones & ID
      ]
   },
   {
   "id": "svs",
   "name": "Services",
   "subnav": 
      [
      _PAGEIDX.tss, //TS Settings
      _PAGEIDX.ntp, //Nit Params
      _PAGEIDX.qad //QAM Audio
      ]
   },
   {
   "id": "std",
   "name": "Studio",
   "subnav": 
      [
      _PAGEIDX.ctl, //control
      _PAGEIDX.inv //Inventory
      ]
   },
   {
   "id": "vbi",
   "name": "VBI",
   "subnav": 
      [
      _PAGEIDX.cpt, //captions
      _PAGEIDX.ttx //teletext
      ]
   },
   {
   "id": "vid",
   "name": "Video",
   "subnav": 
      [
      _PAGEIDX.enc, //Encoder
      _PAGEIDX.dec  //Decoder
      ]
     }
   ],
    
//PRODUCT INDEXES 
_PRDIDX = 
   {
   "unk":  0,       "dspm":  1,      "sedj":  2,      "edj411":  3,    "sol411_1": 4,   "sol411_2":  5,
   "dta":  6,       "dpi":  7,       "adcd":  8,      "mhub":  9,      "mhhd":  10,     "shdp": 11,
   "mhd422":  12,   "e5110": 13,     "hd2qam": 14,    "rd70":  15,     "rd60": 16,      "en40": 17,
   "en80":  18,     "y2qam": 19,     "en41": 20,      "en81":  21,     "en91": 22,      "en10": 23,
   "en20": 24,      "max": 25 //update accordingly
   },
   
_PRODUCT = 
   {
   "UNKNOWN":                    {         "id":   0      },
   "DISPLAYMATE":                {         "id":   1      },
   "SIGNEDJE":          
      {
      "id":   2,
      "name":  "signEdje",
      "color": "#74A89C",
      "navColor": "#77725C",
      "subnavColor": "#4C6B63",
      "numAudios":   0,
      "tabs":  
         [  
         _TABIDX.dsb, // Dashboard
         _TABIDX.ntw, // Network
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp  // help
         ]
      },
      
   "EDJE4111":          
      {
      "id":   3,
      "name":  "edje-4111", 
      "color": "#B19D32",
      "navColor": "#847228",
      "subnavColor": "#77725C",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.dsb, // Dashboard
         _TABIDX.ntw, // Network
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp  // help
         ]
      },
   "SOLOIST411_HW1":        {        "id":   4      },
   "SOLOIST411_HW2":    
      {
      "id":   5,
      "name":  "soloist-4111_hw2",
      "color": "#754B92",
      "navColor": "#77725C",
      "subnavColor": "#77725C",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.dsb, // Dashboard
         _TABIDX.ntw, // Network
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp  // help
         ]
      },   
   "DTA":               
      {
      "id":   6,
      "name":  "dta",
      "color": "#98B572",
      "navColor": "#77725C",
      "subnavColor": "#77725C",
      "numAudios":   0,
      "tabs":
         [
         _TABIDX.dtv, // DTV Config
         _TABIDX.sys, // System
         _TABIDX.upg  // Upgrade
         ]
      },
   
   "DPI":               
      {
      "id":   7,
      "name":  "dpi",
      "color": "#990000",
      "navColor": "#77725C",
      "subnavColor": "#540000",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.chs, //channels
         _TABIDX.ntw, //Network
         _TABIDX.sys, // System
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp // Help
         ]
      },
      
   "ADCODE":{        "id":   8     },
   "MEDIAHUB":    {  "id":   9     },
   "MEDIAHUBHD":        
      {
      "id":   10,
      "name":  "mediahub-hd",
      "color": "#D06700",
      "navColor": "#77725C",
      "subnavColor": "#7C3C01",
      "numAudios":   2,
      "tabs":  
         [
          _TABIDX.svc, // Service
          _TABIDX.prf, // Profile
          _TABIDX.vid, // Video
          _TABIDX.vbi, // VBI
          _TABIDX.aud, // Audio
          _TABIDX.pid, // PID
          _TABIDX.cas, // CAS
          _TABIDX.std, // Studio
          _TABIDX.sys, // System
          _TABIDX.sec, // Security
          _TABIDX.upg, // Upgrade
          _TABIDX.hlp //  Help
          ]
      },
      
   "SOLOISTHDPRO":      
      {
      "id":   11,
      "name":  "SoloistHD_Pro",
      "color": "#336699",
      "navColor": "#77725C",
      "subnavColor": "#244663",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.dsb, // Dashboard
         _TABIDX.ntw, // Network
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp  // help
         ]
      },
      
   "MEDIAHUBHD_422":    
      {
      "id":   12,
      "name":  "mHUB-HD422",
      "color": "#27273F",
      "navColor": "#515177",
      "subnavColor": "#515177",
      "numAudios":   4,
      "tabs":  
         [
         _TABIDX.svc, // Service
         _TABIDX.prf, // Profile
         _TABIDX.vid, // Video
         _TABIDX.vbi, // VBI
         _TABIDX.aud, // Audio
         _TABIDX.pid, // PID
         _TABIDX.cas, // CAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "EDJE5110":          
      {
      "id":   13,
      "name":  "edje-5110",
      "color": "#965F26",
      "navColor": "#336699",
      "subnavColor": "#7C3C01",
      "numAudios":   2,
      "tabs":  
         [
          _TABIDX.svc, // Service
          _TABIDX.prf, // Profile
          _TABIDX.vid, // Video
          _TABIDX.vbi, // VBI
          _TABIDX.aud, // Audio
          _TABIDX.pid, // PID
          _TABIDX.cas, // CAS
          _TABIDX.sys, // System
          _TABIDX.sec, // Security
          _TABIDX.upg, // Upgrade
          _TABIDX.hlp //  Help
          ]
      },
      
   "HDMI2QAM":          
      {
      "id":   14,
      "name":  "hdmi2qam",
      "color": "#339999",
      "navColor": "#77725C",
      "subnavColor": "#006666",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.qam, // QAM/RF Modulator
         _TABIDX.svs, // Services
         _TABIDX.ipo, // IP Out
         _TABIDX.eas, // EAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "RD70":  {  "id":   15    },
   
   "RD60":              
      {
      "id":   16,
      "name":  "RD60", //NOTE GE 12/22/2010:  Not in sync w/ misc_defs.hpp. Original name: RD-60
      "color": "#492F92",
      "navColor": "#555555",
      "subnavColor": "#35276D",
      "numAudios":   8,
      "tabs":  
         [
         _TABIDX.inp, // Input
         _TABIDX.rdv, // Video
         _TABIDX.rda, // Audio
         _TABIDX.cas, // CAS
         _TABIDX.rdb, // VBI
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "EN40":              
      {
      "id":   17,
      "name":  "EN40", //NOTE GE 12/22/2010:  Not in sync w/ misc_defs.hpp. Original name: EN-40
      "color": "#0B3456",
      "navColor": "#336699",
      "subnavColor": "#336699",
      "numAudios":   4,
      "tabs":  
         [
         _TABIDX.svc, // Service
         _TABIDX.mod, // Modulator
         _TABIDX.prf, // Profile
         _TABIDX.vid, // Video
         _TABIDX.aud, // Audio
         _TABIDX.vbi, // VBI
         _TABIDX.pid, // PID
         _TABIDX.cas, // CAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "EN80":              
      {
      "id":   18,
      "name":  "EN80", //NOTE GE 12/22/2010:  Not in sync w/ misc_defs.hpp. Original name: EN-80  
      "color": "#0B3456",
      "navColor": "#336699",
      "subnavColor": "#336699",
      "numAudios":   4,
      "tabs":  
         [
         _TABIDX.svc, // Service
         _TABIDX.mod, // Service
         _TABIDX.prf, // Profile
         _TABIDX.vid, // Video
         _TABIDX.aud, // Audio
         _TABIDX.vbi, // VBI
         _TABIDX.pid, // PID
         _TABIDX.cas, // CAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "YUV2QAM":           
      {
      "id":   19,
      "name":  "yuv2qam",
      "color": "#006400",
      "navColor": "#77725C",
      "subnavColor": "#008000",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.qam, // QAM/RF Modulator
         _TABIDX.svs, // Services
         _TABIDX.ipo, // IP Out
         _TABIDX.eas, // EAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "EN41": {   "id":   20 },
   
   "EN81":              
      {
      "id":   21,
      "name":  "EN81", //NOTE GE 12/22/2010:  Not in sync w/ misc_defs.hpp. Original name: EN-81
      "color": "#0B3456",
      "navColor": "#336699",
      "subnavColor": "#336699",
      "numAudios":   8,
      "tabs":  
         [
         _TABIDX.svc, // Service
         _TABIDX.mod, // Modulator
         _TABIDX.prf, // Profile
         _TABIDX.vid, // Video
         _TABIDX.aud, // Audio
         _TABIDX.vbi, // VBI
         _TABIDX.pid, // PID
         _TABIDX.cas, // CAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
   "EN91":              
      {
      "id":   22,
      "name":  "EN91", 
      "color": "#0B3456",
      "navColor": "#336699",
      "subnavColor": "#336699",
      "numAudios":   8,
      "tabs":  
         [
         _TABIDX.svc, // Service
         _TABIDX.mod, // Modulator
         _TABIDX.prf, // Profile
         _TABIDX.vid, // Video
         _TABIDX.aud, // Audio
         _TABIDX.vbi, // VBI
         _TABIDX.pid, // PID
         _TABIDX.cas, // CAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
      
    "EN10":
      {
      "id":   23,
      "name":  "EN10",
      "color": "#339999",
      "navColor": "#77725C",
      "subnavColor": "#006666",
      "numAudios":   0,
      "tabs":  
         [
         _TABIDX.qam, // QAM/RF Modulator
         _TABIDX.svs, // Services
         _TABIDX.ipo, // IP Out
         _TABIDX.eas, // EAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
   "EN20":
      {
      "id":   24,
      "name":  "EN20",
      "color": "#990000",
      "navColor": "#77725C",
      "subnavColor": "#540000",
      "numAudios":   2,
      "tabs":  
         [
         _TABIDX.svs, // Services
         _TABIDX.qam, // QAM/RF Modulator
         _TABIDX.qen, // Video
         _TABIDX.aud, // Audio
         _TABIDX.qvb, // VBI
         _TABIDX.qpd, // PID
         _TABIDX.cas, // CAS
         _TABIDX.eas, // EAS
         _TABIDX.sys, // System
         _TABIDX.sec, // Security
         _TABIDX.upg, // Upgrade
         _TABIDX.hlp //  Help
         ]
      },
   "MAX": { "id":   25    }  //update accordingly

   },
   
   
   
_MODE_FEC_STR = 
   [
   "","","","","","","","","","",                                                                  // 0-9
   "","QPSK_1/2","QPSK_2/3","QPSK_3/4","","QPSK_5/6","QPSK_6/7","QPSK_7/8","","",                  // 10-19
   "","QPSK_1/4","QPSK_1/3","QPSK_2/5","QPSK_3/5","QPSK_4/5","QPSK_8/9","QPSK_9/10","","",         // 20-29
   "","","","","","","","","","",                                                                  // 30-39
   "","","16APSK_2/3","16APSK_3/4","16APSK_4/5","16APSK_5/6","","","16APSK_8/9","16APSK_9/10",     // 40-49
   "","","","32APSK_3/4","32APSK_4/5","32APSK_5/6","","","32APSK_8/9","32APSK_9/10",               // 50-59
   "","","","16QAM_3/4","","","","16QAM_7/8","","",                                                // 60-69
   "","","","","","","","","","",                                                                  // 70-79
   "","8PSK_3/5","8PSK_2/3","8PSK_3/4","","8PSK_5/6","","","8PSK_8/9","8PSK_9/10"                  // 80-89
   ],
   
_MAXNUMAUDIOS = 8, //Adjust accordingly
_DEMODPAGEPOS = 1, //position in tab (from left to right, starting at 0) where the demod page is located within the INPUT Tab 

_SUBNAV_DEF_STATE =     "none",
_PAGE_ID =              "page",
_SUBNAV_ITEM_CLASS =    "subnavigationitem",  //NOTE..  Case sensitive.. Must match definition in myles.css file.
_RD_SDI_MTRX_PASSTHRU_0_VAL = ((_PRODUCT.RD60.numAudios*2) + 1),
_RD_SDI_MTRX_PASSTHRU_1_VAL = _RD_SDI_MTRX_PASSTHRU_0_VAL + 2,
_UISTATE = 
   {
   "UNKNOWN":           -1,
   "INIT":              0,
   "INSYNC":            1,
   "DISCONNECTED":      2,
   "ERROR":             4
   },

//WARNING!!:  The following enum matches the one contained in /daemon/sys/sys_main.hpp (koala-9).
//They must be in synch. If one changes the other one must change accordingly   last updated 8-12-10 mt
//Reserved values are not used. 

_BOARDID = 
   [
   "DE01",      "DE10",      "EN01",      "EN10",      "C621",      "C622",      "C623",      "PI10",
   "MX01",      "MX10",      "MX11",      "MX10",      "BQ11",      "BQ12",      "BQ13",      "BQ14",
   "BB11",      "BB12",      "BB13",      "BB14",      "BB15",      "HQ01",      "HQ10"
   ],

_BROWSER = 
   {
   "NETSCAPE":    1,
   "IE":          2,
   "OPERA":       3,
   "KONQUEROR":   4,
   "MOZILLA":     5,
   "SAFARI":      6,
   "CHROME":      7,
   "UNKNOWN":     -1
   },
/*
 * NOTE GE 10/14/2010:  _DECODERSTATUSARRAY and _DECODERSTATUSIMGARRAY. Must be in sync w/ TDecStatus enum on the server. (See misc_defs.cpp).
 * If one changes, so must the other.
 */ 
_DECODERSTATUSARRAY =   ["UNKNOWN", "STOPPED", "DECODING", "PAUSED", "STOPPING", "FEATURE_LOCKED", "ENCRYPTED"],
_DECODERSTATUSIMGARRAY = ["blankled.gif", "red.gif", "green.gif", "yellow.gif", "yellow.gif", "red.gif", "red.gif"],

_DECODERCHROMAARRAY = ["--N/A--", "420", "422", "444"],

/*
 * NOTE GE 02/25/2010:
 *    _DECRYPTSTATUSARRAY and  _DECRYPTSTATUSIMGARRAY must be in sync w/ TDecryptStatus enum on the server (see video_defs.hpp).
 *    If one changes, so must the other.
 */
_DECRYPTSTATUSARRAY = ["Free To Air", "Invalid Key", "Decrypting", "UNKNOWN"], 
_DECRYPTSTATUSIMGARRAY = ["fta.gif", "lockred.gif", "unlock.gif", "none.gif"],

/*
 * NOTE GE 10/14/2010:  _DECODERINPUTARRAY. Must be in sync w/ TDcdrInput enum on the server. (See video_defs.cpp).
 * If one changes, so must the other.
 */ 
_DECODERINPUTARRAY =     ["ASI", "RF1", "RF2", "IP"],

_MPAA_RATING = 
   {
   "NOTRATED":    0,
   "G":           1,
   "RESERVED1":   2,
   "RESERVED2":   3,
   "RESERVED3":   4,
   "RESERVED4":   5,
   "RESERVED5":   6,
   "PG":          7,
   "RESERVED6":   8,
   "PG13":        9,   
   "RESERVED7":   10,
   "RESERVED8":   11,
   "RESERVED9":   12,
   "R":           13,
   "RESERVED10":  14,
   "NC17":        15
   },

//NOTE:  This array must be in synch w/ the enum described above.  
//If one changes the other one must change accordingly
_MPAA_RATING_STR = 
   [
   "Not Rated",   //0
   "G",           //1
   "",            //2
   "",            //3
   "",            //4
   "",            //5
   "",            //6
   "PG",          //7
   "",            //8
   "PG-13",       //9
   "",            //10
   "",            //11
   "",            //12
   "R",           //13
   "",            //14
   "NC-17"        //15
   ],


//WARNING!!:  This enum must be in synch w/ TStarRating enum (Server Side).  
//If one changes the other one must change accordingly
_STAR_RATING = 
   {
   "NOTRATED":             0,
   "NONE":                 1,
   "HALF":                 2,
   "ONE":                  3,
   "ONEPLUSHALF":          4,             
   "TWO":                  5,
   "TWOPLUSHALF":          6,             
   "THREE":                7,
   "THREEPLUSHALF":        8,             
   "FOUR":                 9,
   "FOURPLUSHALF":         10,             
   "FIVE":                 11
   },

//NOTE:  This array must be in synch w/ the enum described above.  
//If one changes the other one must change accordingly

_STAR_RATING_STR = 
   [
   "Not Rated",   //0
   "-",           //1            
   "+",           //2
   "*",           //3   
   "*+",          //4   
   "**",          //5
   "**+",         //6
   "***",         //7
   "***+",        //8
   "****",        //9
   "****+",       //10
   "*****"        //11
   ],
   
   
   
//WARNING!!:  This enum must be in synch w/ TSLVContent enum (Server Side).   
//If one changes the other one must change accordingly
_SLV_CONTENT = 
   {
   "UNKNOWN":              0,
   "NONE":                 1,
   "SEX":                  2,
   "LANGUAGE":             3,
   "VIOLENCE":             4,
   "SEXLANGUAGE":          5,
   "SEXVIOLENCE":          6,
   "LANGUAGEVIOLENCE":     7,
   "SEXLANGUAGEVIOLENCE":  8     
   },

//NOTE:  This array must be in synch w/ the enum described above.  
//If one changes the other one must change accordingly
_SLV_CONTENT_STR = 
   [
   "N/A",
   "NONE",
   "S",
   "L",
   "V",
   "SL",
   "SV",
   "LV",
   "SLV"
   ], 


_CLOSED_CAPTION_STR = 
   [
   "NONE", 
   "CC"
   ],
_STEREO_STR = 
   [
   "N/A",
   "YES"
   ],
_DVC_PATH =                      "/media/hd0/dvc/",  
_ADTEC_SCH_PATH =                _DVC_PATH, //NOTE:   Must be in sync w/ ADTEC_SCHEDULE_PATH in requestHandler   
_AUDIORATE_PRECISION  =          2,
_DEFAULT_REFRESH_TIMEOUT =       3000, 
_NUMOSDREGIONS =                 4, //CONSTANT number of OSD regions.
_MIN_RELEASE_YEAR =              1900,
_MINTELTXTLINE =                 6, 
_MAIN_MENU_ID =                  "tab",
_MAX_RELEASE_YEAR =              2030,
_MAXTELTXTLINE =                 22,
_PLAYLIST_ID_PREFIX =            "li_playlist_", //prefix for playlist id
_PTXLINEENABLEDPREFIX =          "ecmd_ptx_lineenabled",
_PTX0LINEENABLEDPREFIX =          "ecmd0_ptx_lineenabled",
_PTX1LINEENABLEDPREFIX =          "ecmd1_ptx_lineenabled",
_QAM_SYMBOL_RATE_PRECISION =     3,
_SCH_LI_PREFIX =                 "li_sch", //prefix for LI items representing scheduler files
_SCH_NOT_LOADED_REGEX=           /SCHEDULE NOT LOADED/, //NOTE:  This definition must be in synch w/ SCH_NOT_LOADED in

//_SCHSTREVENTTYPE array defines the strings to be displayed for each supported event type.
//NOTE: This array must be in sync w/ enum _SCHEVENTTYPE (see above).

_SCHSTREVENTTYPE = 
   [
   "CUSTOM",
   "PLAYLIST",
   "PLAYSPOT",
   "MULTICAST RECEIVE",
   "STOP DECODER",
   "MULTICAST OFF",
   "CLEAR SCHEDULE"
   ],
_SCHWILDCARD =          "--",
_TELTXTLINEOFFSET =              _MINTELTXTLINE,
_TUNER_PROFILE_PREFIX =          "prf",
_XHR_OK_STATUSCODE =             200,
_NEWLINE =                       "\r\n",
_MYLESURL =                      "/myles",
_REQHANDLER =                    "/requestHandler", //loc for requestHandler Fast CGI server
_EITSCH_LOC =                    "/eit_scheduler",  //loc for eit_scheduler FastCGI server
_DEFAULT_MEDIA_PATH  =           "/media/hd0/media",  //default path for media files
_DEFAULT_ERROR_VAL =             -1,
_CONT_STR =                      "...",
_HEX_PREFIX =                    "0x",

//Max number of times the cc count has not been increased w/out throwing an error.. 
//For HDMI2QAMs, this is polled every 6 secs approx..   Thus, after 24 seconds of this variable not being updated, an error is detected

_MAX_ECMD_CC_COUNT_TOLERANCE =   4, 
_NAVIGATION_DELAY_TIMEOUT =      750,
_INVALID_DURATION_IN_MSECS =     -1,
_STATUS_PANEL_RETRY_INTERVAL =   2000,
_STATUS_PANEL_TIMEOUT_VAL =      10000,
_STATUSPANEL_MAX_STR_LEN =       16,
_STATUS_PANEL_MAX_PROFILE_LEN =  11,
_STATUS_PANEL_PROF_LEN_OFFSET =  5,
_TERSE_TOKEN_POS =               2,
_VERBOSE_TOKEN_POS =             3,
_MULTICAST_TOKEN_POS =           4,

_MIN_DPI_CHANNEL =               1,
_MAX_DPI_CHANNEL =               12,

_SMIL_EXT_STR =                  ".smil",
_DATE_DELIM =                    "/",
_TIME_DELIM =                    ":",
_MAX_MCAST_PORT_VAL =            65535,
_MAX_PGM_NUM   =                 65535,
_MIN_PID_VAL =                   32,
_MAX_PID_VAL =                   8190,



//MESSAGES
_FILEEXISTSSTR             = "FILE ALREADY EXISTS", //response from requestHandler when the given file exists on the DB
_UNIMPLCMDMSG              = "Unimplemented command", //substring returned for unimplemented commands on the API
_REQHANDLER_ERR_MSG_PREFIX = "REQHANDLER ERROR: ",
_LBM_PING_SUCCESS_RESPONSE  = "LBAND Modulator is Available.", //NOTE: This must match the same definition in the server. If one changes, so must the other.  See <BRANCH>/solib/cmdh/g_sys.cpp
_IPREGEX                   =  /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\s*/,  //Regular expression object used when testing for IP addresses

_DEFAULT_NUM_AUDIO_TRACKS  = 2,
_NUM_AUDIOTRACKS_MHHD422   = 4,


//_REQHANDLER_ERR_MSG  = "ERROR: Ajax request not successful.  More information may be available in the system log.",
_NOSCHINFOMSG        = "No Schedule Files Available",
_STR_AUTO = "AUTO",
/********************************************************************************************************************************
 * PLEASE NOTE:  Enums are not supported in JAVASCRIPT. However, we can mimic them in the following fashion...
 *               Every enum value (or in this case, object property) must be assigned, as they are not automatically increased by 1.
*********************************************************************************************************************************/
//enum to identify requests made to requestHandler.  
//NOTE:  This enum must be sync'ed with TReqId enum in requestHandler. See <project>/app/myles/requestHandler.cpp
_REQID =  
   {//Global Requests.  Valid range 100-199
   "GETPRODUCTINDEX":            100,
   "GETFTPMARKUP":               101,
   "GETINFOBLURBS":              102,
   "ISVALIDFILE":                103,
   "RENAMEFILE":                 104,
   "PACKFILES":                  105,
   "MAKESYSPROFILE":             106,
   "GETPROFILECONTENTS":         107,
   
   //FIRMWARE tab. Valid range 200-299  
   "GETUNINSTALLEDFIRMWARE":     200,
   "GETINSTALLEDFIRMWARE":       201,
   "HANDLEVERSION":              202,
   "SHOWPEERS":                  203, //reserved
   
   //INVENTORY tab. Valid range 300-399
   "GETPLAYLISTS":               300,
   "GETINVENTORY":               301,
   "GETPLAYLISTCONTENTS":        302,
   "CREATEPLAYLIST":             303,
   "ADDTOPLAYLIST":              304,
   "DELETEFILE":                 305,
   "REMOVEFROMPLAYLIST":         306,
   "REARRANGEPLAYLIST":          307,
   "GETINVENTORYCOUNT":          308,
   "APPENDPLAYLIST":             309,
   "SEARCHINVENTORY":            310,
   
   //Display tab. Valid range 400-499
   "GETOSDGRAPHICS":             400,
   
   //Scheduler Tab. Valid range 500-599
   "GETSCHFILES":                500, 
   "CREATESCHEDULE":             501,
   "GETPLAYSPOTFILES":           502,
   "GETSCHFILECONTENTS":         503,
   "UPDATESCHFILE":              504,
   "ADDEVTTOSCHFILE":            505,

   //Demod Tab. Valid Range 600-649
   "GETDEMODPROFILELIST":        600,
   
   //Modulator Tab. Valid Range 650-699
   "GETMODULATORPROFILELIST":    650,
   
   "GETRDAUDIOVALUES":           700,
   
   //Placeholder to avoid syntax errors
   //when inserting new values to this enum.
   "REQ_ID_MAXVAL":            10000                    
     
   },
   
   
/*******************************************
 * WARNING:  This enum must be in synch w/ the server.
 * If one changes, the other one must be changed accordingly.
 * See TEitReqId under /app/eit_scheduler/src/eit_scheduler_main.hpp
 *******************************************/
_EIT_REQID =  
   {
   "GETAVAILABLEPROGRAMS":            0,
   "SHOWGUIDEFORPROGRAM":             1,
   "SUBMITOVERRIDEENTRY":             2,
   "DELETEOVERRIDEENTRY":             3,
   
   //Placeholder to avoid syntax errors
   //when inserting new values to this enum.
   "EIT_REQID_MAXVAL":                 10000
   },
   
   
   
_TARGET_TYPE =  //enum that defines the diferent types of targets for drag-n-drop operations
   {
   "ERROR":   -1,
   //inventory tab. Range 0-99
   "RECORD":   0,
   "PLAYLIST": 1,
   
   //scheduler tab. Range 100-199
   "SCHEDULE": 100,
   
   //trashbin
   "TRASH":   1000
   },

_DATERES = 
   {
   "OK":                      0,
   "INVALIDFORMAT":           1,
   "INVALIDMONTH":            2,
   "INVALIDDAY":              3,
   "INVALIDDAYSINMONTH":      4,
   "INVALIDDAYSINFEB":        5
   },
   

_DATE_ERR_STR = 
   [
   "",
   "Please enter date as mm/dd/yyyy",
   "Month must be between 1 and 12.",
   "Day must be between 1 and 31.",
   "Month has only 30 days!",
   "Invalid days in February"
   ],

//LOG PANEL DEFINES
_LOGPNLDIV =         "logPnlDiv", //Warning....   This must be in synch w/ (hardcoded) reference in CSS file, and myles.html file..  If one changes, so must the other ones.
_LOGPNLLINKID =       "logPnlLinkId",
_LOGPNLBODYDIV =     "logPnlBodyDivId", 



_BITSPERMBIT =    _MILLION,
_BITSPERKBITS =   _THOUSAND,
_KBITSPERMBITS =  (_BITSPERMBIT/_BITSPERKBITS),


//STATUS PANEL
_MAXAUDIOERRORS = 15, 

_DEFAULT_PROFILE_VAL = "DEFAULT",
_TRASHBIN_ID =  "trashbin_li",

_Y2KVAL =                     2000, 
_Y2KTHRESHOLD =               30,           
_BINNUMBASE =                 2,
_OCTALNUMBASE =               8,
_DECNUMBASE =                 10,
_HEXNUMBASE =                 16,
_DEFAULT_NUM_BASE =           _DECNUMBASE,

_YEARSINCENTURY  =            100,
_HOURSPERDAY =                24,
_MINUTESPERHOUR =             60,
_SECONDSPERMINUTE =           60,
_FRAMESPERSECOND =            30,
_MINUTESPERDAY =              (_HOURSPERDAY*_MINUTESPERHOUR),
_SECONDSSPERDAY =             (_MINUTESPERDAY*_SECONDSPERMINUTE),
_FRAMESPERDAY =               (_SECONDSSPERDAY*_FRAMESPERSECOND),
_MINMONTHSINYEAR =            1,
_MAXMONTHSINYEAR =            12,
_STDLEAPYRFREQUENCY =         4,
_MAXDAYSINFEBRUARY =          29,
_MINDAYSINMONTH =             1,
_MAXDAYSINMONTH =             31,
_MINYY =                      9,
_MAXYY =                      29,
_MINYEAR =                    2009,
_MAXYEAR =                    2029,
_MAXHOUR =                    (_HOURSPERDAY-1),
_MAXMINUTE =                  (_MINUTESPERHOUR-1),
_MAXSECOND =                  (_SECONDSPERMINUTE-1),
_MAXFRAME =                   (_FRAMESPERSECOND-1),

_MILISECONDSPERSECOND   =  _THOUSAND,
_MILISECONDSPERMINUTE   =  _MILISECONDSPERSECOND * 60,
_MILISECONDSPERHOUR     =  _MILISECONDSPERMINUTE * 60,

_MONTH = 
   {
   "JANUARY":        1,
   "FEBRUARY":       2,
   "MARCH":          3,
   "APRIL":          4,
   "MAY":            5,
   "JUNE":           6,
   "JULY":           7,
   "AUGUST":         8,
   "SEPTEMBER":      9,
   "OCTOBER":        10,
   "NOVEMBER":       11,
   "DECEMBER":       12
   },

_MAXDAYSINMONTHARR = 
   [
   -1, //N/A 
   31, //JANUARY
   29, //FEBRUARY
   31, //MARCH
   30, //APRIL
   31, //MAY
   30, //JUNE
   31, //JULY
   31, //AUGUST
   30, //SEPTEMBER
   31, //OCTOBER
   30, //NOVEMBER
   31  //DECEMBER
   ],

_DAYSOFWEEK = //Zero-based string array representing days of the week (from 0 to 6) 
   [
   "Sun",
   "Mon",
   "Tue",
   "Wed",
   "Thu",
   "Fri",
   "Sat"
   ],


//unordered list type (used to set drag-drop functionality
_ULTYPE = 
   {
   "PLAYLIST": 10,
   "SCHEDULE": 20
   },

_MENU_RENDER_DELAY_IN_MS   =  750
;   

/****************************************************************************************************
                                       Global Variables
****************************************************************************************************/

var  
_blurbObjs = null,
_currPage = null,
_currTab = null,
_debug = false, //DEVELOPMENT ONLY. Used to trigger debug statements
_globalModalPanel = null,
_hasDemodProfile = false,
_hasFirmwareUpload = false,
_hasFeatureUpload = false,
_mainState,
_subnavState, 
_currUiState = _UISTATE.UNKNOWN,
_logIndex = 0,
_programIndex = 0, 
_putPbArr = [], //put progress bar array
_putfilesCounter = 0,
_rebootingStarted = false,
_videoThumbnailTimeout = null,
_audioThumbnailTimeout = null,
_timeoutCode = null, //used to set and cancel formStatus timeout
_unconfiguredAudio = [],   //array of flags to identify audio hardware errors. one entry per audio input 
setting = [], //global associative array containing all settings requested to the api
_tsnArray = [], //track select array
_updateStatus, //Identifies if status panel must be updated. Prevents server overload   
_uploadPanel, //this object holds the markup for the FTP upload component
_helpPanel = null, //Object that holds the markup for bubble help panels
_resizeHelp = null, //resize object for help panel
_unitConnected = true, //indicates status of server connection
_profileIndex = 0,  //keeps track of position in global array of profiles (PROFILE)
_qv1Flag_line1 = true, //bolean to identify the current line when parsing the QV1 command
_slowRequestReady = true, //used for slow updates to the status panel of players
_initUpdateTimeoutCode,
_updateTimeoutCode,
_msgArrayIndex = 0,
_currentField, 
_countAudioErrors = [], //counter of audio errors
_playlistListArr = null, //array of playlist references (in JSON Format). Used for inventory and sch tabs.
_playspotListArr = null, //array of media files (in JSON Format). 
_numAudioTracks = 2,
_ntModSupported = false,                             
   // Browser History Manager
_bookmarkedState = YAHOO.util.History.getBookmarkedState(_MAIN_MENU_ID),
_initialState,
_waitTimeout = -1,
_numPnpBoards = 0,
_tnrPrfFound = [], 
//HDMI2QAM closed caption detection
_ecmdCCCount = 0, 
_ecmd0CCCount = 0, //for HDMI2QAM and YUV2QAM only
_ecmd1CCCount = 0, //for HDMI2QAM and YUV2QAM only
_ecmdTTCount = 0,
_ecmd0TTCount = 0, //for HDMI2QAM and YUV2QAM only
_ecmd1TTCount = 0, //for HDMI2QAM and YUV2QAM only
_ecmdCCCountTolerance = 0, 
_ecmd0CCCountTolerance = 0, //for HDMI2QAM and YUV2QAM only
_ecmd1CCCountTolerance = 0, //for HDMI2QAM and YUV2QAM only
_ecmdTTCountTolerance = 0,
_ecmd0TTCountTolerance = 0, //for HDMI2QAM and YUV2QAM only
_ecmd1TTCountTolerance = 0, //for HDMI2QAM and YUV2QAM only
_vbiHstLineCount = [],
_thermostat = null,
_refreshStatusPanel = true
;/*****************************************************************************
* @file
* @author Original: Jim Littleton
* @author Contributors: German Escallon
* @date Created: 2008/08/06
* @date Last Edit: $Date$ by $Author$
* Description: Entry point for MyLES.
******************************************************************************/
var       
ecmd0Regex = /^\s*ECMD0/,
ecmd1Regex = /^\s*ECMD1/,
_lastParseResponseValid,
ecmdXRegex = /^\s*(ECMD(\d+)?).*/i,

/*******************************************************************************
 * Returns the current command handler for ECMD
 ******************************************************************************/
GetECMD = function(command)
   {
   return command.replace(ecmdXRegex, '$1').toLowerCase();
   },

/*******************************************************************************
 * Splits the given command line and tokenizes it by the given delimiter
 ******************************************************************************/
ParseCommand = function(commandLine, delimiter)
   {
   return commandLine.split( delimiter ); // Break command line into tokens
   },

/*************************************************************************
* Entry point of the parser.  
* Parses each command found in the response data and dynamically calls the appropriate function
*************************************************************************/
ParseResponse = function(response)
   {
   var errorFlag = false;
   var x = 0;
   var responseData = (response.responseText).split("\n");
   var apiCall; // var used for dynamic function calls
 
   for (x = 0; x < responseData.length; x++)
      { // Loop through each line of the response data
      var command = CleanupString(responseData[x]); //removes extra space characters and end of the line chars
      if(command.length>0)
         {
         var tempArray = command.split(' '); // Break the response data line into individual words
         
         //creates the api call using the first two words of the response
         apiCall = tempArray[0].toLowerCase( ) + '_' + tempArray[1].toLowerCase( ); 

         // also.. sysd_barklist_port/host/interval etc..  
         //TODO:  Modify algorithm..  these conditions (3 words in response) should be captured in custom parser 
         if( (apiCall == "sysd_barklist" && tempArray.length > 4))
            {
            apiCall = tempArray[0].toLowerCase( ) + '_' + tempArray[1].toLowerCase( ) + '_' + tempArray[2].toLowerCase( );           
            }
         switch(apiCall)
            {
            //standard verbose requests
            case "sysd_barklist": //barklist
            case "sysd_mlf": //mirror list file
            case "sysd_hip": //host ip
            case "sysd_hom": //host mode
            case "sysd_hot": //host timer
            case "sysd_tiz": //timezone
            case "sysd_xcp": //xcp
            case "sysd_xck": //xcp key
            case "sysd_snmp": //snmp
            case "sysd_htp": //http port
               
            case "dcmd_blank": //blank
            case "dcmd_daf": // decoder Active Format Descriptor
            case "dcmd_mer": // multicast error recovery
            case "dcmd_der": // dvb error recovery
            case "dcmd_dlt": // dvb latency
            case "dcmd_ecr": // Encryption Mode
            case "dcmd_rad": // rtp autodetect
            case "dcmd_rpt": // repeat
            case "dcmd_spm": // spdif mode
            case "dcmd_stc": // stc beacon
            case "dcmd_vid": // display target
            case "dcmd_vol": // VOLUME

            case "ecmd_afd": // Active Format descriptor
            case "ecmd_agn": // audio group number
            case "ecmd_asf": // audio sample frequency
            case "ecmd_asm": // asimode
            case "ecmd_cca": // constant capture
            case "ecmd_cht": // chromatype
            case "ecmd_cif": // CONTROL INTERFACE
            case "ecmd_clc": // closed caption
            case "ecmd_drc": // video input
            case "ecmd_eco": // E OSD
            case "ecmd_ecr": // Encryption Mode
            case "ecmd_hsize": // Horizontal Size
            case "ecmd_inp": // video input
            case "ecmd_la0": // language code audio 0
            case "ecmd_la1": // language code audio 1
            case "ecmd_lna": // line number
            case "ecmd_maj": // MAJOR CHANNEL
            case "ecmd_min": // MINOR CHANNEL
            case "ecmd_ofs": // Filter Spatial
            case "ecmd_oft": // Filter Temporal
            case "ecmd_rct": // record time
            case "ecmd_rdu": // record duration
            case "ecmd_rit": //Remote insert
            case "ecmd_rvd": // videoDrop
            case "ecmd_sas": // secondary audio (on/off)
            case "ecmd_spt": // sdi passthrough
            case "ecmd_svm": // sdi video mode
            case "ecmd_ton": // tables on
            case "ecmd_tmr": // transmux rate
            case "ecmd_ltt": // teletext descriptor
            case "ecmd_mrm": // tmr mode
            case "ecmd_vaf": // video autofill
            case "ecmd_vbs": // vbisource
            case "ecmd_ven": // video CODEC
            case "ecmd_vfc": // Video Field Coding
            case "ecmd_vid": // Video Type
            case "ecmd_vrt": // video bit rate
            case "ecmd_vsize": // Vertical Size
            case "ecmd_hue": // Video Hue
            case "ecmd_bri": // Video Brightness
            case "ecmd_con": // Video Contrast
            case "ecmd_sat": // Video Saturation

            // HDMI2QAM - TODO - need to review for a more dynamic way to grab 2
            case "ecmd0_tmr": // transmux rate
            case "ecmd1_tmr": // transmux rate
            case "ecmd0_inp": // video input
            case "ecmd1_inp": // video input
            case "ecmd0_vrt": // video input
            case "ecmd1_vrt": // video input
            case "ecmd0_clc": // closed caption
            case "ecmd1_clc": // closed caption
            case "ecmd0_min": // MINOR CHANNEL
            case "ecmd1_min": // MINOR CHANNEL
            case "ecmd0_maj": // MAJOR CHANNEL
            case "ecmd1_maj": // MAJOR CHANNEL
            case "ecmd0_ton": // tables
            case "ecmd1_ton": // tables
            case "ecmd0_stu": // startup
            case "ecmd1_stu": // startup
            case "ecmd0_vsi":
            case "ecmd1_vsi":
            case "ecmd0_hsi":
            case "ecmd1_hsi":
            case "ecmd0_asm": // asi mode
            case "ecmd0_agn": // audio group number
            case "ecmd1_agn": // audio group number
            case "ecmd0_rit": // Remote insert
            case "ecmd1_rit": // Remote insert
            case "ecmd0_ecr": // Encryption Mode
            case "ecmd1_ecr": // Encryption Mode
            case "ecmd0_afd": // Active Format descriptor
            case "ecmd1_afd": // Active Format descriptor
            case "ecmd0_hsize": // Horizontal Size
            case "ecmd1_hsize": // Horizontal Size
            case "ecmd0_svm": // sdi video mode
            case "ecmd1_svm": // sdi video mode
            case "ecmd0_vaf": // video autofill
            case "ecmd1_vaf": // video autofill
            case "ecmd0_vid": // Video Type
            case "ecmd1_vid": // Video Type
            case "ecmd0_vsize": // Vertical Size
            case "ecmd1_vsize": // Vertical Size
            case "ecmd0_cht": // chromatype
            case "ecmd1_cht": // chromatype
            case "ecmd0_asf": // audio sampling frequency
            case "ecmd1_asf": // audio sampling frequency
               setting[apiCall] = ParseVerbose_std(command);
               break;
            
            //standard terse requests
            
            case "dcmd_a4": //AFD DEscriptor
            case "dcmd_vi": //display target

            case "sysd_si": // tuner input select
            case "ecmd_er": //encoder latency trim
            case "ecmd_ed":   //Entropy Coding
            case "ecmd_mit": // Markin time
            case "ecmd_px": // Preroll
            case "ecmd_s6": // sdi video fault
            case "ecmd_sb": // STC beacon
            case "ecmd0_tb": // type of service
            case "ecmd0_lc": // logical channel number
            case "ecmd1_lc": // logical channel number
               setting[apiCall] = ParseTerse_std(command);
               break;

            case "dcmd_mcn": // decoder multicast connector
            case "dcmd_mlt": // multicast latency
            case "dcmd_mmo": // decoder multicast mode
            case "dcmd_mri": // decoder multicast r ipa
            case "dcmd_mrp": // decoder multicast r port
            case "dcmd_mtu": // decoder multicast timeout
            case "dcmd_stu": // decoder startup command
            case "ecmd_pnu": // program number
            case "ecmd0_pnu": // program number
            case "ecmd1_pnu": // program number
            // case "ecmd_bmo": //vbi mode
            case "sysd_barklist_host": // TODO
            case "sysd_barklist_port": // TODO
            case "sysd_barklist_interval": // TODO

               setting[apiCall] = ParseMulticast(command);
               break;
            
            case "ecmd_aq": //amol pid
            case "ecmd_bp": // BPI pid
            case "ecmd_pp": //PMT pid
            case "ecmd_pr": //PRP pid
            case "ecmd_sx": //Splice Pid
            case "ecmd_tp": //teletext pid
            case "ecmd_ts": //TS Id Pid
            case "ecmd_vp": //VPI Pid
            case "ecmd0_ts": //TS Id Pid
            case "ecmd1_ts": //TS Id Pid
            case "ecmd0_vp": //VPI Pid
            case "ecmd1_vp": //VPI Pid
            case "ecmd0_pp": //PMT pid
            case "ecmd1_pp": //PMT pid
            case "ecmd0_pr": //PRP pid
            case "ecmd1_pr": //PRP pid
            case "ecmd0_tp": //teletext pid
            case "ecmd1_tp": //teletext pid
            case "ecmd0_aq": //amol pid
            case "ecmd1_aq": //amol pid
            case "ecmd0_sx": //Splice Pid
            case "ecmd1_sx": //Splice Pid
               Parse_ecmd_pid(command);
               break;

            // Customized Requests
            case "log_err": // log of errors


            case "dpid_chs":
            case "dpid_tr":
            case "dpid_cn": 
            case "dpid_chm":
            case "dpid_cln":
            case "dpid_spn":
            case "dpid_sli":
            case "dpid_sia":
            case "dpid_spo":
            case "dpid_sca":
            case "dpid_scs":
            case "dpid_ns":

            case "sysd_banner": // banner
            case "sysd_barklist_list":
            case "sysd_bi": // boards information
            case "sysd_cpw": // client username/password
            case "sysd_spw": // server username/password
            case "sysd_dhc": // dhcp
            case "sysd_dst": // dvc status
            case "sysd_dt": //terse dvc status
            case "sysd_fe": // features (terse)
            case "sysd_fea": // features (verbose)
            case "sysd_gip": //gateway ip
            case "sysd_gbm":// gbe management
            case "sysd_ipa": // ipaddress
            case "sysd_ipm": // ip mask
            case "sysd_lm": // L-Band Modulator (terse)
            case "sysd_mf": // manufacturer info
            case "sysd_na": // name (Terse)
            case "sysd_nam": // name (Verbose)
            case "sysd_nip": // NTP Server Addresses
            case "sysd_ns": // Nameserver
            case "sysd_profile": //
            case "sysd_tim": // Time
            case "sysd_upt": // Uptime
            case "sysd_sc": // schname
            case "sysd_saf": // tuner feed
            case "sysd_sts": // tuner stats
            case "sysd_lnb": // tuner feed
            case "sysd_sip": // Stealth IP Address
            case "sysd_snmpvar":
            case "sysd_sup": // Sat Tuner data
            case "sysd_tp": // Tuner Demod Profile

            case "dcmd_aof":
            case "dcmd_dcb":
            case "dcmd_dco": // decoder configuration settings
            case "dcmd_dct": // decoder configuration settings
            case "dcmd_cfg": // decoder configuration settings
            case "dcmd_d2": // Dolby Params
            case "dcmd_da": // DECODEAUDIOPID
            case "dcmd_decodeservice":
            case "dcmd_dit":
            case "dcmd_its": // decoder input transport stream
            case "dcmd_dpn": // decoder program number
            case "dcmd_dus": // decoder status
            case "dcmd_dvb": // dvb-asi mode
            case "dcmd_li": // list
            case "dcmd_mk": //Multicast connector
            case "dcmd_nf": // Terse version of SERVICE INFO
            case "dcmd_oar": // aspect ratio
            case "dcmd_osd": // on screen display
            case "dcmd_ost": // on screen template
            case "dcmd_ovs": // decoder output video scale
            case "dcmd_smx": // decoder sdi audio matrix(verbose)
            case "dcmd_sv": // service detail (terse)
            case "dcmd_s0": // decoder sdi audio matrix(Terse)
            case "dcmd_tr": // decoder transport
            case "dcmd_tsn": // track select
            case "dcmd_uo": //audio offset (terse)
            case "dcmd_us": // terse version of decoder status
            case "dcmd_vm": // volume control
            case "dcmd_vms": // temp control
            
            case "ecmd_a9":// audio mode //Terse
            case "ecmd_ads": // audio input
            case "ecmd_aif": // audio feedback path
            case "ecmd_ain": // audio input
            case "ecmd_alv":// audio level
            case "ecmd_amo":// audio mode
            case "ecmd_api": // audio pid
            case "ecmd_ara": // Aspect Ratio
            case "ecmd_aus":// audio sync
            case "ecmd_bmo": // vbi mode
            case "ecmd_cde": // Confidence Decode
            case "ecmd_cn":// capture filename
            case "ecmd_cd":// CID
            case "ecmd_dbf": // deBlock filter
            case "ecmd_dp":  // dolby parameters (terse)
            case "ecmd_dpa": // dolby parameters (verbose) deprecated
            case "ecmd_ect": // Tones
            case "ecmd_el": // Encoder Latency
            case "ecmd_emh": // encoder sdi audio matrix
            case "ecmd_emx": // encoder sdi audio matrix
            case "ecmd_ex": // encoder sdi audio matrix   (terse)
            case "ecmd_far": // encoder fpga audio router
            case "ecmd_fm":
            case "ecmd_gop": // Group of Pictures
            case "ecmd_lde": // language descriptor
            case "ecmd_mcm":// audio musicam mode
            case "ecmd_mmo": // encoder multicast mode
            case "ecmd_msi": // encoder multicast ipa
            case "ecmd_msp": // encoder multicast port
            case "ecmd_np": // NIT Parameters
            case "ecmd_profile": // profile
            case "ecmd_ptx": // process teletext
            case "ecmd_qv1": // quickview
            case "ecmd_q1": // quickview
            case "ecmd_rtp": // rtp
            case "ecmd_sna": // service name
            case "ecmd_spr": // service Provider
            case "ecmd_ss1": // snapshot1
            case "ecmd_tos": // type of service
            case "ecmd_tr": // ecmd transport
            case "ecmd_ttl": // time to live
            case "ecmd_tx": // Teletext Descriptor
            case "ecmd_vbh": // VBI History
            case "ecmd_vbp": // VBI Parameters
            case "ecmd_vde": // videodetected
            case "ecmd_vms": // temp control
            case "ecmd_ecb": // ColorBars
            case "ecmd_mcn": // encoder multicast connector
            case "eit_sch_gul":                // DTA - EIT

               // HDMI2QAM Specific commands
            case "ecmd0_ads": // audiodsp
            case "ecmd1_ads": // audiodsp
            case "ecmd0_ain": // audio input
            case "ecmd1_ain": // audio input
            case "ecmd0_amo": // audio mode
            case "ecmd1_amo": // audio mode
            case "ecmd0_as": //Audio sync 0
            case "ecmd1_as": //Audio sync 1
            case "ecmd0_av": //audio level
            case "ecmd1_av": //audio level
            case "ecmd0_dp": // Dolby Params
            case "ecmd1_dp": // Dolby Params
            case "ecmd0_eas": // aes
            case "ecmd0_fm":
            case "ecmd0_m0":  //
            case "ecmd0_mcn": // encoder multicast connector
            case "ecmd0_mmo": // encoder multicast mode
            case "ecmd0_msi": // encoder multicast send ipa
            case "ecmd0_msp": // encoder multicast send port
            case "ecmd0_qam": // qam settings
            case "ecmd0_qv1": // audio present, refresh rate, resolution
            case "ecmd1_qv1": // audio present, refresh rate, resolution
            case "ecmd0_q1": // audio present, refresh rate, resolution
            case "ecmd1_q1": // audio present, refresh rate, resolution
            case "ecmd0_rtp": // multicast rtp
            case "ecmd0_sna": // service name
            case "ecmd1_sna": // service name
            case "ecmd0_spr": // service provider
            case "ecmd1_spr": // service provider
            case "ecmd0_tos": // type of service
            case "ecmd0_tr": // tra
            case "ecmd1_tr": // tra
            case "ecmd0_vbh": // vbi history
            case "ecmd1_vbh": // vbi history
            case "ecmd0_ttl": // time to live
            case "ecmd0_np": // nit parameters
            case "ecmd0_ptx": // teletext
            case "ecmd1_ptx": // teletext
            case "ecmd0_alv": // audio level
            case "ecmd1_alv": // audio level
            case "ecmd0_far": // encoder fpga audio router
            case "ecmd1_far": // encoder fpga audio router
            case "ecmd0_mcm":// audio musicam mode
            case "ecmd1_mcm":// audio musicam mode
            case "ecmd0_aus":// audio sync
            case "ecmd1_aus":// audio sync
            case "ecmd0_lde":// language descriptor
            case "ecmd1_lde":// language descriptor
            case "ecmd0_api":// audio pid
            case "ecmd1_api":// audio pid
            case "ecmd0_ara": // Aspect Ratio
            case "ecmd1_ara": // Aspect Ratio
            case "ecmd0_gop": // Group of Pictures
            case "ecmd1_gop": // Group of Pictures
            case "ecmd0_cd":// CID
            case "ecmd0_sl": // SDI Clock Source
            case "ecmd1_sl": // SDI Clock Source

               var dynamicFunction = "CustomParse_" + apiCall;
               try
                  {
                     if (apiCall == "ecmd_profile")
                        {
                        // custom parser for profile needs the raw line on the response, including continuous space characters
                        window[dynamicFunction](responseData[x]);
                        }
                     else
                        {
                        window[dynamicFunction](command);
                        } // Custom functions created dynamically
                  }
               catch (err)
                  {
                  LogMyles("Caught Parse error." + command); // Log the error
                  errorFlag = true;
                  }
               break;

            default:
               LogMyles("Unrecognized Command Error: " + command);// Log the error
               errorFlag = true;
               break;
            }
         }
      }
   _lastParseResponseValid = !errorFlag;
   return !errorFlag;
   },

/*******************************************************************************
 * Returns the fifth word of the response
 ******************************************************************************/
ParseMulticast = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); //parses the command line into tokens   
   return parsedCommand[_MULTICAST_TOKEN_POS]; 
   },

/*******************************************************************************
 * Returns the fourth word of the response
 ******************************************************************************/
ParseVerbose_std = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); //parses the command line into tokens      
   var rawResp = parsedCommand[_VERBOSE_TOKEN_POS];
   var intResp = _NA; //initialize to a non-number.  Do not use NULL (considered 0 by many javascript engines)
   if(!IsHex(rawResp))
      {//skip hex numbers from conversion
      intResp = parseInt(rawResp, 10);
      }
   return isNaN(intResp)? rawResp: intResp; //automatically convert integer responses. 
   },

/*******************************************************************************
 * Returns the third word of the response
 ******************************************************************************/
ParseTerse_std = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); //parses the command line into tokens
   var rawResp = parsedCommand[_TERSE_TOKEN_POS];
   var intResp = _NA; //initialize to a non-number.  Do not use NULL (considered 0 by many javascript engines)
//   if(!IsHex(rawResp))
   if(IsInt(rawResp))
      {//skip hex numbers from conversion
      intResp = parseInt(rawResp, 10);
      }
   return isNaN(intResp)? rawResp: intResp; //automatically convert integer responses.  
   },
   
/*******************************************************************************
 * Parser for Encoder Pid API commands. (Terse)
 ******************************************************************************/
Parse_ecmd_pid = function(line)
   {
   //response e.g:  ECMD PP 0x0020 0032
   var regex = /^\s*ECMD(\d+)?\s+(\w+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s*/i;
   if(regex.test(line))
      {
      var tmpObj = 
         {
         "hex": line.replace(regex, "$3"),
         "dec": parseInt(line.replace(regex, "$4"), 10)
         };
      setting[GetECMD(line) + "_" + line.replace(regex, "$2").toLowerCase()] = tmpObj;
      }
   },
   
/*******************************************************************************
 * Parser for Encoder Pid API commands on dual encoder. (Terse)
 ******************************************************************************/
Parse_ecmd0_pid = function(line)
   {
   return Parse_ecmd_pid(line);
   },

/*-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
*  Custom Parsers
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-*/
/*************  *******************************
* Retrieve FEC parameters
********************************************/
CustomParse_ecmd_fm = function(command)
   {
   //command e.g:
   //ECMD FM 0 0 14 7 0
   var 
      FEC_PROF_POS =            2,
      FEC_L_POS =               3,
      FEC_D_POS =               4,
      FEC_TOSBITS_POS =         5
      ;
   
   var regex = /\s*ECMD\s+FM\s+(\d)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   if(regex.test(command))
      {
      var fmIdx = command.replace(regex, "$1");
      setting["ecmd_fm_"+ fmIdx +"_profile"] =  parseInt(command.replace(regex, "$"+FEC_PROF_POS), _DEFAULT_NUM_BASE );
      setting["ecmd_fm_"+ fmIdx +"_L"] =        parseInt(command.replace(regex, "$"+FEC_L_POS), _DEFAULT_NUM_BASE);
      setting["ecmd_fm_"+ fmIdx +"_D"] =        parseInt(command.replace(regex, "$"+FEC_D_POS), _DEFAULT_NUM_BASE);
      setting["ecmd_fm_"+ fmIdx +"_tosbits"] =  parseInt(command.replace(regex, "$"+FEC_TOSBITS_POS), _DEFAULT_NUM_BASE);
      }
   else
      {
      LogMyles("FM Parser error.  Regular expression did not match response");  
      }
   },
   
/********************************************
  * Retrieve FEC parameters
 ********************************************/
CustomParse_ecmd0_fm = function(command)
   {
   //command e.g:
   //ECMD0 FM 0 0 14 7 0
   var 
      FEC_PROF_POS =            2,
      FEC_L_POS =               3,
      FEC_D_POS =               4,
      FEC_TOSBITS_POS =         5
      ;
   
   var regex = /\s*ECMD0\s+FM\s+(\d)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   if(regex.test(command))
      {
      var fmIdx = command.replace(regex, "$1");
      setting["ecmd0_fm_"+ fmIdx +"_profile"] =  parseInt(command.replace(regex, "$"+FEC_PROF_POS), _DEFAULT_NUM_BASE );
      setting["ecmd0_fm_"+ fmIdx +"_L"] =        parseInt(command.replace(regex, "$"+FEC_L_POS), _DEFAULT_NUM_BASE);
      setting["ecmd0_fm_"+ fmIdx +"_D"] =        parseInt(command.replace(regex, "$"+FEC_D_POS), _DEFAULT_NUM_BASE);
      setting["ecmd0_fm_"+ fmIdx +"_tosbits"] =  parseInt(command.replace(regex, "$"+FEC_TOSBITS_POS), _DEFAULT_NUM_BASE);
      }
   else
      {
      LogMyles("FM Parser error.  Regular expression did not match response");  
      }
   
   },   
      
/********************************************
* Retrieve NIT parameters
********************************************/
 
CustomParse_ecmd_np = function(line)
   {
//   var regex = /^ECMD\s+NP\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\w+)\s+(\d+)\s+(\d+)\s*/i;
   var regex = /^ECMD0?\s+NP\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\w+)(\s+(\d+)\s+(\d+))?\s*/i;
   if(regex.test(line))
      {
     
      var npObj = 
         {
         "frequency":            parseInt(line.replace(regex, "$1"),10),
         "symbol":               parseInt(line.replace(regex, "$2"),10),
         "service":              parseInt(line.replace(regex, "$3"),10),
         "modulation":           parseInt(line.replace(regex, "$4"),10),
         "fecInner":             parseInt(line.replace(regex, "$5"),10),
         "fecOuter":             parseInt(line.replace(regex, "$6"),10),
         "polarization":         parseInt(line.replace(regex, "$7"),10),
         "orbitalPosition":      parseInt(line.replace(regex, "$8"),10),
         "positionFlag":         parseInt(line.replace(regex, "$9"),10),
         "bandwidth":            parseInt(line.replace(regex, "$10"),10),
         "hierarchyInfo":        parseInt(line.replace(regex, "$11"),10),
         "codeRateLPStream":     parseInt(line.replace(regex, "$12"),10),
         "guardInterval":        parseInt(line.replace(regex, "$13"),10),
         "transmitMode":         parseInt(line.replace(regex, "$14"),10),
         "otherFrequencyFlag":   parseInt(line.replace(regex, "$15"),10),
         "annex":                line.replace(regex, "$16"),
         "dvbType":              parseInt(line.replace(regex, "$17"),10),
         "dvb2Rolloff":          parseInt(line.replace(regex, "$18"),10)
         };
      setting["ecmd_np"] = npObj;
      }
   else
      {
      LogMyles("FM Parser error.  Regular expression did not match response");
      }
   },   
   
/********************************************
 * Retrieve NIT parameters
 ********************************************/
CustomParse_ecmd0_np = function(command)
   {
   CustomParse_ecmd_np(command);
   },

/*******************************************************************************
 * Retrieve qam parameters
 ******************************************************************************/
CustomParse_ecmd0_qam = function(command)
   {       
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   switch(parsedCommand[2])
      {
      case "MOD_QAM_MODE=":
         setting["ecmd0_qam_mode"] = parsedCommand[3];
         break;
      case "MOD_BAUD_RATE=":
         setting["ecmd0_qam_baud_rate"] = parsedCommand[3];
         break;
      case "MOD_ENCODING=":
         setting["ecmd0_qam_encoding"] = parsedCommand[3];
         break;
      case "UPCON_CHANNEL_NUM=":
         setting["ecmd0_qam_channelNumber"] = parsedCommand[3];
         break;
      case "MOD_CENTER_FREQ=":
         setting["ecmd0_qam_centerFrequency"] = parsedCommand[3];
         break;
      case "MOD_INVERT=":
         setting["ecmd0_qam_invert"] = parsedCommand[3];
         break;         
      case "UPCON_POWER_LVL=":
         setting["ecmd0_qam_powerLevel"] = parseInt(parsedCommand[3], 10);
         break;
      case "UPCON_OUTPUT_FREQ=":
          setting["ecmd0_qam_outputFreq"] = parseInt(parsedCommand[3], 10);
          break;
      case "MOD_VIDEO=":
          setting["ecmd0_qam_videoType"] = parsedCommand[3];
          break;
      }
   },

/*******************************************************************************
 * Retrieve QV1 parameters
 ******************************************************************************/
CustomParse_ecmd0_qv1 = function(command)
   {
   /* ECMD0 QV1 1920x1080 29i 18.56M
    * ECMD0 QV1 1280x 720 59p 18.34M
    * ECMD0 QV1 1920x1080 30i 18.56M
    * ECMD0 QV1 1DD 224k 1DD  Off 48 (NOTE GE 06/14/2010: This line is currently ignored). 
    *
    * ECMD0 QV1 No Video Detected !!
    */
   var line1Regex = /^\s*(ECMD[\d])\s+QV1\s+(\d+\s*x\s*\d+)\s+(\d+[i|p])\s+([\d|\.])+M\s*/i; //line 1 of QV1 response
   var line1NoVideoRegex = /^\s*(ECMD[\d])\s+QV1\s+No Video Detected !!\s*/i; //line 1 of QV1 response
   var frameRateInx, cmdh = GetECMD(command);
   if(line1Regex.test(command))
      {
      setting[cmdh + "_qv1_resolution"] = command.replace(line1Regex, "$2");
      frameRateInx = cmdh+"_qv1_frameRate";
      setting[frameRateInx] = command.replace(line1Regex, "$3");
      setting[cmdh + "_qv1_videoRate"] = command.replace(line1Regex, "$4");
      }
   else if(line1NoVideoRegex.test(command))
      {//No video detected
      setting[cmdh + "_qv1_resolution"] = _NA;
      frameRateInx = cmdh+"_qv1_frameRate";
      setting[frameRateInx] = _NA;
      setting[cmdh + "_qv1_videoRate"] = _NA;
      }
   
   },

/*******************************************************************************
 * Retrieve Q1 parameters
 ******************************************************************************/
CustomParse_ecmd0_q1 = function(command)
   {
   /* ECMD0 Q1 1920x1080 29i 18.56M
    * ECMD0 Q1 1280x 720 59p 18.34M
    * ECMD0 Q1 1920x1080 30i 18.56M
    * ECMD0 Q1 1DD 224k 1DD  Off 48 (NOTE GE 06/14/2010: This line is currently ignored). 
    *
    * ECMD0 Q1 No Video Detected !!
    */
   var topRegex = /^\s*(ECMD[\d])\s+Q1\s+(\d+)\s*x\s*(\d+)\s+(\d{1,2}[a-z])\s+([\d\.]+[a-z])\s*/i;
   var line1NoVideoRegex = /^\s*(ECMD[\d])\s+Q1\s+No Video Detected !!\s*/i; //line 1 of Q1 response
   var cmdh = GetECMD(command) + "_q1";
   if(topRegex.test(command))
      {
      setting[cmdh] = {
         "hsize": parseInt(command.replace(topRegex, "$2"), 10),
         "vsize": parseInt(command.replace(topRegex, "$3"), 10),
         "frate": command.replace(topRegex, "$4"),
         "tmr": command.replace(topRegex, "$5")
         };
      }
   else if(line1NoVideoRegex.test(command))
      {//No video detected
      setting[cmdh] = {"hsize": null, "vsize": null, "frate": _NA, "tmr": _NA};
      }
   },

/*******************************************************************************
 * Retrieve QV1 parameters
 ******************************************************************************/
CustomParse_ecmd1_qv1 = function(command)
   {
   CustomParse_ecmd0_qv1(command);
   },

/*******************************************************************************
 * Retrieve Q1 parameters
 ******************************************************************************/
CustomParse_ecmd1_q1 = function(command)
   {
   CustomParse_ecmd0_q1(command);
   },

/*******************************************************************************
 * Retrieve tone pair parameters
 ******************************************************************************/
CustomParse_ecmd_ect = function(command)
   {    
   //e.g responses
   
   // For mHUB-HD422, EN-40, EN-80:
   //ECMD ECT EncodeColorbarsTone= PAIR0=OFF PAIR1=OFF PAIR2=OFF PAIR3=OFF
   //ECMD ECT EncodeColorbarsFreq= PAIR0=1000 PAIR1=2000 PAIR2=2500 PAIR3=440
   //ECMD ECT EncodeColorbarsMute= CHAN0=OFF CHAN1=OFF CHAN2=OFF CHAN3=OFF CHAN4=OFF CHAN5=OFF CHAN6=OFF CHAN7=OFF
   // For others:
   //ECMD ECT EncodeColorbarsTone= PAIR0=OFF PAIR1=OFF
   //ECMD ECT EncodeColorbarsFreq= PAIR0=1000 PAIR1=2000 
   //ECMD ECT EncodeColorbarsMute= CHAN0=OFF CHAN1=OFF CHAN2=OFF CHAN3=OFF
      
   var ectToneRegex = /^$/;
   var ectFreqRegex = /^$/;
   var ectMuteRegex = /^$/;
   
   switch(GetNumAudioInputs())
      {  
      case 2:
         ectToneRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsTone=\s+PAIR0=(.+)\s+PAIR1=(.+)\s*/i;
         ectFreqRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsFreq=\s+PAIR0=(.+)\s+PAIR1=(.+)\s*/i;
         ectMuteRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsMute=\s+CHAN0=(.+)\s+CHAN1=(.+)\s+CHAN2=(.+)\s+CHAN3=(.+)\s*/i;
         break;
      
      case 4:
         ectToneRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsTone=\s+PAIR0=(.+)\s+PAIR1=(.+)\s+PAIR2=(.+)\s+PAIR3=(.+)\s*/i;
         ectFreqRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsFreq=\s+PAIR0=(.+)\s+PAIR1=(.+)\s+PAIR2=(.+)\s+PAIR3=(.+)\s*/i;
         ectMuteRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsMute=\s+CHAN0=(.+)\s+CHAN1=(.+)\s+CHAN2=(.+)\s+CHAN3=(.+)\s+CHAN4=(.+)\s+CHAN5=(.+)\s+CHAN6=(.+)\s+CHAN7=(.+)\s*/i;
         break;
      
      case 8:
         ectToneRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsTone=\s+PAIR0=(.+)\s+PAIR1=(.+)\s+PAIR2=(.+)\s+PAIR3=(.+)\s+PAIR4=(.+)\s+PAIR5=(.+)\s+PAIR6=(.+)\s+PAIR7=(.+)\s*/i;
         ectFreqRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsFreq=\s+PAIR0=(.+)\s+PAIR1=(.+)\s+PAIR2=(.+)\s+PAIR3=(.+)\s+PAIR4=(.+)\s+PAIR5=(.+)\s+PAIR6=(.+)\s+PAIR7=(.+)\s*/i;
         ectMuteRegex = /^\s*ECMD\s+ECT\s+EncodeColorbarsMute=\s+CHAN0=(.+)\s+CHAN1=(.+)\s+CHAN2=(.+)\s+CHAN3=(.+)\s+CHAN4=(.+)\s+CHAN5=(.+)\s+CHAN6=(.+)\s+CHAN7=(.+)\s+CHAN8=(.+)\s+CHAN9=(.+)\s+CHAN10=(.+)\s+CHAN11=(.+)\s+CHAN12=(.+)\s+CHAN13=(.+)\s+CHAN14=(.+)\s+CHAN15=(.+)\s*/i;
      }
      
   
   if(ectToneRegex.test(command))
      {
      setting["ecmd_ect_0_tone"] = command.replace(ectToneRegex, "$1");
      setting["ecmd_ect_1_tone"] = command.replace(ectToneRegex, "$2");
     
      if(GetNumAudioInputs()>2) 
         {
         setting["ecmd_ect_2_tone"] = command.replace(ectToneRegex, "$3");
         setting["ecmd_ect_3_tone"] = command.replace(ectToneRegex, "$4");
      
         if(GetNumAudioInputs()>4)
            {
            setting["ecmd_ect_4_tone"] = command.replace(ectToneRegex, "$5");
            setting["ecmd_ect_5_tone"] = command.replace(ectToneRegex, "$6");
            setting["ecmd_ect_6_tone"] = command.replace(ectToneRegex, "$7");
            setting["ecmd_ect_7_tone"] = command.replace(ectToneRegex, "$8");
            }
         }
      }
   else if(ectFreqRegex.test(command))
      {
      setting["ecmd_ect_0_frequency"] = parseInt(command.replace(ectFreqRegex, "$1"), 10);
      setting["ecmd_ect_1_frequency"] = parseInt(command.replace(ectFreqRegex, "$2"), 10);
      if(GetNumAudioInputs()>2) 
         {
         setting["ecmd_ect_2_frequency"] = parseInt(command.replace(ectFreqRegex, "$3"), 10);
         setting["ecmd_ect_3_frequency"] = parseInt(command.replace(ectFreqRegex, "$4"), 10);
         if(GetNumAudioInputs()>4)
            {
            setting["ecmd_ect_4_frequency"] = parseInt(command.replace(ectFreqRegex, "$5"), 10);
            setting["ecmd_ect_5_frequency"] = parseInt(command.replace(ectFreqRegex, "$6"), 10);
            setting["ecmd_ect_6_frequency"] = parseInt(command.replace(ectFreqRegex, "$7"), 10);
            setting["ecmd_ect_7_frequency"] = parseInt(command.replace(ectFreqRegex, "$8"), 10);
            }
         }
        
      }
   else if(ectMuteRegex.test(command))
      {
      setting["ecmd_ect_0_l_mute"] = command.replace(ectMuteRegex, "$1");
      setting["ecmd_ect_0_r_mute"] = command.replace(ectMuteRegex, "$2");
      setting["ecmd_ect_1_l_mute"] = command.replace(ectMuteRegex, "$3");
      setting["ecmd_ect_1_r_mute"] = command.replace(ectMuteRegex, "$4");
      
      
      if(GetNumAudioInputs()>2) 
         {
         setting["ecmd_ect_2_l_mute"] = command.replace(ectMuteRegex, "$5");
         setting["ecmd_ect_2_r_mute"] = command.replace(ectMuteRegex, "$6");
         setting["ecmd_ect_3_l_mute"] = command.replace(ectMuteRegex, "$7");
         setting["ecmd_ect_3_r_mute"] = command.replace(ectMuteRegex, "$8");
         
         if(GetNumAudioInputs()>4)
            {
            setting["ecmd_ect_4_l_mute"] = command.replace(ectMuteRegex, "$9");
            setting["ecmd_ect_4_r_mute"] = command.replace(ectMuteRegex, "$10");
            setting["ecmd_ect_5_l_mute"] = command.replace(ectMuteRegex, "$11");
            setting["ecmd_ect_5_r_mute"] = command.replace(ectMuteRegex, "$12");
            setting["ecmd_ect_6_l_mute"] = command.replace(ectMuteRegex, "$13");
            setting["ecmd_ect_6_r_mute"] = command.replace(ectMuteRegex, "$14");
            setting["ecmd_ect_7_l_mute"] = command.replace(ectMuteRegex, "$15");
            setting["ecmd_ect_7_r_mute"] = command.replace(ectMuteRegex, "$16");
            }
         }
      }
   else
      {
      LogMyles("Parse Error in ECMD ECT API command");
      }
   },

/*******************************************************************************
 * Retrieve Encoder Latency Setting
 ******************************************************************************/
CustomParse_ecmd_el = function(line)
   {
   var regex = /^\s*ECMD\s+EL\s+(\d+)\s*/;
   if(regex.test(line))
      {
      setting["ecmd_el"] = parseInt(line.replace(regex, "$1"), 10);
      }
   else
      {
      LogMyles("Parse Error in ECMD EL API command");
      }
   },
   
/*******************************************************************************
 * Retrieve snmpvar
 ******************************************************************************/
CustomParse_sysd_snmpvar = function(command)
   {       
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   switch(parsedCommand[3])
      {
      case "ROCOMMUNITY":
         setting["sysd_snmpvar_rocommunity"] = parsedCommand[5];
         break;

      case "RWCOMMUNITY":
         setting["sysd_snmpvar_rwcommunity"] = parsedCommand[5];
         break;

      case "TRAPCOMMUNITY":
          setting["sysd_snmpvar_trapCommunity"] = parsedCommand[5];
          break;    
       
      case "TRAP2SINK":
          setting["sysd_snmpvar_trapSink"] = parsedCommand[5];
          break;    
          
      }
   },
         

   
/********************************************
* Retrieve entire BarkList List cmds
********************************************/
 
CustomParse_sysd_barklist_list = function(command)
   { 
   var parsedCommand = command.substring(command.indexOf('=')+2);
   setting["sysd_barklist_list"] = parsedCommand; 
   },   

/*******************************************************************************
 * Parser for log error
 ******************************************************************************/
CustomParse_log_err = function(command)
   {
   
//      LOG ERR Jul 12 16:45:23 PRODUCTION No [ETRANS]: 31022 Encoder 1 Stopping. Video detected = 1 Video rate = 15266000 AudioOnly = 0 MPEG = 2 size = 480v720h secondaryAudio = 0
   var regex = /^\s*LOG\s+ERR\s+([a-zA-Z]{3}\s+\d+\s+\d\d*:\d{2}:\d{2})\s+([\w|\s]*)\s+\[(\w*)\]:\s+(.*)\s*/i;
   if(regex.test(command))
      {
      setting["log_err_date"][_logIndex] = command.replace(regex, "$1");
      setting["log_err_device"][_logIndex] = command.replace(regex, "$2"); 
      setting["log_err_process"][_logIndex] = command.replace(regex, "$3");
      setting["log_err_msg"][_logIndex] = command.replace(regex, "$4");
      _logIndex++; 
      }
   else
      {
      LogMyles("Line " + command + " failed regex test.");
      }
   },

/*******************************************************************************
 * Parser for TR (TRANSPORT) command of the decoder
 ******************************************************************************/
CustomParse_dpid_tr = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];          
   setting["dpid_tr_decodeStatus_"+ch] = GetDecodeStatus(parsedCommand[3]); //get status
   setting["dpid_tr_decodeImage_"+ch] = GetDecodeImage_dpi(parsedCommand[3]); //get led image
   setting["dpid_tr_filename_"+ch] = command.substring(command.indexOf('"')+1, command.lastIndexOf('"'));
   if(setting["dpid_tr_filename_"+ch].length>37) //TODO: Replace magic values
      {
      setting["dpid_tr_filename_"+ch] = setting["dpid_tr_filename"].substring(0, 34) + "..."; //TODO: Replace magic values
      }
   setting["dpid_tr_rate_"+ch] = (parseInt(parsedCommand[9], 10)/1000);       //TODO: Replace magic values
   setting["dpid_tr_progress_"+ch] = parseInt(parsedCommand[parsedCommand.length - 2], 10);     //TODO: Replace magic values
   },

CustomParse_dpid_chs = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ');
   var ch = parsedCommand[2];
   setting['dpid_chs_'+ch] = parsedCommand[4];
   },
   
CustomParse_dpid_ns  = function(line)
   {
//   response e.g: DPID NS 1 0 1  0  1  INACTIVE ALL 00:00:00 23:59:59 DTMF_TONE #123 *123 7000 0 00:00:00 SPOT
   var regex = /\s*DPID\s+NS\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+\:\d+\:\d+)\s+(\d+\:\d+\:\d+)\s+(\w+)\s+(\#\d+)\s+(\*\d+)\s+(\d+)\s+(\d+)\s+(\d+\:\d+\:\d+)\s+(\w+)\s*/i;

   //var pos = {"idx": 0, "input": 1, "idxr": 2, "inputr": 3, "idxx": 4, "mode": 5, "dayson": 6, "timeon": 7, "timeoff": 8, "type": 9, "startcondition": 10, 
   //         "stopcondition": 11, "preroll": 12, "postroll": 13, "availtime": 14, "endby": 15};
   
   if(regex.test(line))
      {
      if(setting["dpid_ns"]===undefined){setting["dpid_ns"] = [];}
      var obj = 
         {
         "mode":              line.replace(regex, "$6"), 
         "dayson":            line.replace(regex, "$7"), 
         "timeon":            line.replace(regex, "$8"),
         "timeoff":            line.replace(regex, "$9"), 
         "type":              (line.replace(regex, "$10")).toUpperCase(),
         "startcondition":    line.replace(regex, "$11"),
         "stopcondition":     line.replace(regex, "$12"),
         "preroll":           parseInt(line.replace(regex, "$13"), 10),
         "postroll":          parseInt(line.replace(regex, "$14"), 10),
         "availtime":         line.replace(regex, "$15"),
         "endby":             (line.replace(regex, "$16")).toUpperCase()
         };
      setting["dpid_ns"][parseInt(line.replace(regex, "$1"), 10)] = obj;
      }
   else
      {
      LogMyles("Parse error in DPID NS. Line:\"" + line + "\"");
      }
   },
   
/**************** Parser for channel mode **************/   

CustomParse_dpid_chm = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ');      
   setting["dpid_chm_"+parsedCommand[2]] = parsedCommand[4];      
   },
      

CustomParse_dpid_cln  = function(command)
   {     
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];     
   var chname = parsedCommand[4];
   setting["dpid_cln_"+ch] = chname;

   },
   

CustomParse_dpid_spn = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var spn = parsedCommand[4];
   setting["dpid_spn_"+ch] = spn;
   },
   

CustomParse_dpid_sli = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var sli = parsedCommand[4];
   setting["dpid_sli_"+ch] = sli;
   },
   

CustomParse_dpid_sia  = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var sia = parsedCommand[4];
   setting["dpid_sia_"+ch] = sia;  
   },   

CustomParse_dpid_spo  = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var spo = parsedCommand[4];
   setting["dpid_spo_"+ch] = spo;     
   },

CustomParse_dpid_sca  = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var sca = parsedCommand[4];
   setting["dpid_sca_"+ch] = sca;
   },
   

CustomParse_dpid_scs = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var ch = parsedCommand[2];
   var scs = parsedCommand[4];
   setting["dpid_scs_"+ch] = scs;     
   },
   

CustomParse_dpid_cn  = function(line)
   {
   //DPID CN C 0 01001
   var regex = /\s*DPID\s+CN\s+([CPN])\s+(\d+)\s+([\w|\/]*)/i;
   if(regex.test(line))
      {
      if(setting["dpid_cn"]===undefined){setting["dpid_cn"] = {};}
      if(setting["dpid_cn"][line.replace(regex, "$1").toLowerCase()]===undefined) {    setting["dpid_cn"][line.replace(regex, "$1").toLowerCase()] = [];}
      setting["dpid_cn"][line.replace(regex, "$1").toLowerCase()][parseInt(line.replace(regex, "$2"), 10)] = line.replace(regex, "$3").toLowerCase();
      }
   else
      {
      LogMyles("Parse error in DPID CN. Line:\"" + line + "\"");
      }
   },      
      

/********************************************
* Parser for cpw setting
********************************************/   
 
CustomParse_sysd_cpw = function(line)
   {
   
   //cpw e.g
   //SYSD CPW CltUserPassword= <username>,<password>
   var regex = /\s*SYSD\s+CPW\s+CLTUSERPASSWORD\s*=\s*(\w+)\,(\w+)/i;
   if(setting["sysd_cpw"]===undefined){setting["sysd_cpw"] = {};}
   if(regex.test(line))
      {
      var tmpObj = 
         {
         "user":  line.replace(regex, "$1"),
         "pwd":      line.replace(regex, "$2")
         };
      setting["sysd_cpw"] = tmpObj;
      }
   else
      {
      LogMyles("Parse error in CPW API command. Line:\"" + line + "\"");
      }
   },

/***************************************************************************
 * Parser for cpw setting
**************************************************************************/
 
CustomParse_sysd_spw = function(command) 
   {

   var parsedCommand = ParseCommand(command, ' ');
   var spwArray = parsedCommand[3].split(",");
   setting["sysd_spw_username"] = spwArray[0];
   setting["sysd_spw_password"] = spwArray[1];
   },
      
      
/*******************************************************************************
 * Parser for dhcp setting
 ******************************************************************************/   
CustomParse_sysd_dhc = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["sysd_dhc_0"] = "ON"
   setting["sysd_dhc_"+parsedCommand[2]] = parsedCommand[4]; 
   },

/******************************************
 * Parses the SYSD DT API command (Terse).
 *******************************************/
CustomParse_sysd_dt = function(line)
   {
   /*
    * sysd dt 10/24/11 15:16:02 /media/hd0/dvc/prfAdtecHDTV2_10242011_141422.DVC
    */
   setting["sysd_dt"] = setting["sysd_dt"]? setting["sysd_dt"]: [];
   var regex = /^\s*SYSD\s+DT\s+[\d+\/\d+\/\d+\s+\d+\:\d+\:\d+\s+]*([\w\/\.]+)[\s+\d+\/\d+\/\d+\s+\d+\:\d+\:\d+]*\s*/i;
   var profileRegex = /^prf([\-\w]+)/;
   if(regex.test(line))
      {
      var filepath = line.replace(regex, "$1");
      var basename = GetFileBasename(filepath);
      var ext = GetFileExtension(filepath);
      if((ext.toUpperCase()=="DVC") && (profileRegex.test(basename)))
         {
         setting["sysd_dt"].push(basename.replace(profileRegex, "$1"));
         }
      else
         {
         LogMyles("Invalid entry in SYSD DT parser.");
         }
      }
   else
      {
      LogMyles("Error in local SYSD DT parser.");
      }
   
   },
 
CustomParse_sysd_dst = function
   (
   line
   )
   {
   //line e.g:  SYSD DST /media/hd0/dvc/tnrtestg.DVC 02/15/36 06:45:51 t1
   var prfRegex = /^$/;
   switch(GetProductId())
      {
      case _PRODUCT.RD60.id:
         prfRegex = /\s*SYSD\s+DST\s+([\/|\w|_|\-]*\/[\w|\-|_]+\.dvc)\s+(\d{1,2})\/(\d{1,2})\/(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\s+t(\d)\s*/i;
         break;
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
         prfRegex = /\s*SYSD\s+DST\s+([\/|\w|_|\-]*\/[\w|\-|_]+\.dvc)\s+(\d{1,2})\/(\d{1,2})\/(\d{1,2})\s+(\d{1,2}):(\d{1,2}):(\d{1,2})\s*/i;
         break;
      }
   var prfRegexPos = 
      {
      "filename":    1,
      "month":       2,
      "day":         3,
      "year":        4,
      "hour":        5,
      "minute":      6,
      "second":      7,
      "tunerIndex":  8 //only available in RD-60 products
      };
   if(prfRegex.test(line))
      {
      switch(GetProductId())
         {
         case _PRODUCT.RD60.id:
            var prfTnrInx = parseInt(line.replace(prfRegex, "$"+prfRegexPos.tunerIndex), 10);
            if(!isNaN(prfTnrInx))
               { 
               if(!_tnrPrfFound[prfTnrInx])
                  {//found the latest profile loaded for the specified tuner
                  setting["sysd_dst_prf" + prfTnrInx] = line.replace(prfRegex, "$"+prfRegexPos.filename);
                  _tnrPrfFound[prfTnrInx] = true; //set flag, so subsequent lines (outdated) are ignored.
                  }
               else
                  {//an updated profile for this tuner was already found.  Ignore 
                  }
               }
            break;

         case _PRODUCT.EN40.id:
         case _PRODUCT.EN80.id:
         case _PRODUCT.EN81.id:
         case _PRODUCT.EN91.id:
            if(!_modPrfFound)
               {
               setting["sysd_dst_prf"] = line.replace(prfRegex, "$"+prfRegexPos.filename);
               _modPrfFound = true; //sets the flag so that subsequent lines (outdated) are ignored.
               }
            break;
            
         }
            
      }
   else
      { 
      LogMyles("DVCSTATUS unrecognized response");
      }
   
   },
   
/********************************************
* Parser for IPA setting
********************************************/   
 
CustomParse_sysd_ipa = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["sysd_ipa_0"] = "192.255.255.0"
   setting["sysd_ipa_"+parsedCommand[2].toLowerCase()] = parsedCommand[4]; 
   },
   
/********************************************
* Parser for banner command.  Version number is included in the response
********************************************/    
 
CustomParse_sysd_banner = function(line)
   {
//      SYSD BANNER Edje 5110 Version 1.01.17, Created Sat Jul 10 21:19:55 EDT 2010

   var regex = /^\s*SYSD\s+BANNER\s+[\w\-_\s]+\s+Version\s+([\w\-\.]+).+/i;
   if(regex.test(line))
      {
      setting["sysd_banner_version"] = line.replace(regex, "$1");
      }
   
   },

/********************************************
* Customized parser for BOARDSINFO command.  
********************************************/    
 
CustomParse_sysd_bi = function(command)
   {
   //command e.g:
   // SYSD BI 2   BB12  "PC77 ver 1.2"

   var boardInfoRegex = /^\s*SYSD\s+BI\s+(\d{1,2})\s+(\w{4})\s+"((\w|\s|\.)+)"/i ;
   var SLOTPOS = 1,     IDPOS = 2, NAMEPOS = 3;
   if(boardInfoRegex.test(command))
      {
      setting["sysd_bi_slot" + _numPnpBoards] =  command.replace(boardInfoRegex, "$"+SLOTPOS);
      setting["sysd_bi_id" + _numPnpBoards] =    command.replace(boardInfoRegex, "$"+IDPOS).toUpperCase();
      setting["sysd_bi_name" + _numPnpBoards] =    command.replace(boardInfoRegex, "$"+NAMEPOS);
      _numPnpBoards++;
      }
   else
      {
      LogMyles("ERROR- Board Info response failed regex test");
      }
      
   },

/********************************************
* Customized parser for VBIMODE BMO command.  
********************************************/    
 
CustomParse_ecmd_bmo = function(command)
   {
   //command e.g:
   // ECMD bmo VbiMode1 Mode= ON

   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd_bmo_1"] =  parsedCommand[5]; 

   },
   
/********************************************
* Parser for ip mask setting
********************************************/   
 
CustomParse_sysd_ipm = function(command)
   {
   var IPM_IDX_POS = 2;
   var IPM_POS =     4;
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["sysd_ipm_1"] = "0.255.255.0"
   setting["sysd_ipm_"+parsedCommand[IPM_IDX_POS]] = parsedCommand[IPM_POS]; 
   },
   

/********************************************
* Parser for Terse version of LBANDMODULATOR | LBM | LM command
********************************************/   
 
CustomParse_sysd_lm = function(line)
   {
   // SYSD LM 0 -30.0 18 3 13 1080 1 1 15 20.7353 3 N/A N/A 1 5000 6080 1 0 0
   var lmRegex = /^\s*SYSD\s+LM\s+(\d+)\s+([\d\.\-]+)\s+([\d\.\-]+)\s+(\d+)\s+(\d+)\s+([\d\.\-]+)\s+(\d+)\s+(\d+)\s+([\d\.\-]+)\s+([\d\.\-]+)\s+(\d+)\s+([\w\/]+)\s+([\w\/]+)\s+(\d+)\s+([\d\.\-]+)\s+([\d\.\-]+)\s+([\d\.\-]+)\s+([\w\/]+)\s+([\w\/]+)\s+([\w\/]+)\s+([\w\/]+)\s*/i;
   var LMPOS =
      {
      "TRANSMIT": 1, "POWER": 2, "OCCUPPIEDBANDWIDTH": 3, "TYPE":4, "MODE": 5,
      "FREQUENCY": 6, "SPECTRUMINVERSION": 7, "RATEPRIORITY": 8, "SYMBOLRATE": 9,
      "INTERFACERATE": 10, "ROLLOFF": 11, "PILOT": 12, "FECFRAMETYPE": 13, "CARRIERMOD": 14,
      "LOCALOSCILLATOR": 15, "RFFREQUENCY": 16, "UPLINKMODE": 17, "REF_CLOCK":18, "REF_CLOCK_COMB":19, "LBANDFREQ": 20,"IFFREQ":21,"MAX": 20 
      };
//   SYSD LM 0 -30.0 18.75 3 13 1450 1 1 15 20.7353 2 N/A N/A 1 5000 6450 1 N/A N/A 1450000000 N/A
   if(lmRegex.test(line))
      {
      _ntModSupported = true; //indicates that this unit has an L-Band modulator attached to it.
      var lmObj = 
         {
         "transmit":             line.replace(lmRegex, "$"+LMPOS.TRANSMIT),
         "power":                line.replace(lmRegex, "$"+LMPOS.POWER),
         "occuppiedbandwidth":   line.replace(lmRegex, "$"+LMPOS.OCCUPPIEDBANDWIDTH),
         "type":                 line.replace(lmRegex, "$"+LMPOS.TYPE),
         "mode":                 line.replace(lmRegex, "$"+LMPOS.MODE),
         "frequency":            line.replace(lmRegex, "$"+LMPOS.FREQUENCY),
         "spectruminversion":    line.replace(lmRegex, "$"+LMPOS.SPECTRUMINVERSION),
         "ratepriority":         line.replace(lmRegex, "$"+LMPOS.RATEPRIORITY),
         "symbolrate":           line.replace(lmRegex, "$"+LMPOS.SYMBOLRATE),
         "interfacerate":        line.replace(lmRegex, "$"+LMPOS.INTERFACERATE),
         "rolloff":              line.replace(lmRegex, "$"+LMPOS.ROLLOFF),
         "pilot":                line.replace(lmRegex, "$"+LMPOS.PILOT),
         "fecframetype":         line.replace(lmRegex, "$"+LMPOS.FECFRAMETYPE),
         "carriermod":           line.replace(lmRegex, "$"+LMPOS.CARRIERMOD),
         "localoscillator":      line.replace(lmRegex, "$"+LMPOS.LOCALOSCILLATOR),
         "rffrequency":          line.replace(lmRegex, "$"+LMPOS.RFFREQUENCY),
         "uplinkmode":           line.replace(lmRegex, "$"+LMPOS.UPLINKMODE),
         "refClock":             line.replace(lmRegex, "$"+LMPOS.REF_CLOCK),
         "refClockCombined":     line.replace(lmRegex, "$"+LMPOS.REF_CLOCK_COMB),
         "lbandFrequency":       line.replace(lmRegex, "$"+LMPOS.LBANDFREQ),
         "ifFrequency":          line.replace(lmRegex, "$"+LMPOS.IFFREQ)
         };
      setting["sysd_lm"] = lmObj;  
      }
   else
      {
      _ntModSupported = false; //This unit does NOT have an L-Band modulator attached to it.
      var lmNotInstalledRegex = /^\s*SYSD\s+LM\s+2604\s*$/i; //2604 is the error code for the expected terse response when the hardware does not support this   command.
      
      if(!lmNotInstalledRegex.test(line))
         { //Defensive code.
         LogMyles("Parse Error: SYSD LM line failed both regex tests.");
         }
      }
   },

/*******************************************************************************
 * Parser for ntcp server command
 ******************************************************************************/
CustomParse_sysd_nip = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var NIP_POS = 3;
   var NIP_DELIM = ",";
   //gets the first argument of the response and removes the "," immediately after it
   //e.g 
   //Response: SYSD NIP 0.0.0.0, 255.255.255.255, 1.1.1.1, 3.3.3.3 
   // THEN: setting["sysd_nip"] = 0.0.0.0
   setting["sysd_nip"] = parsedCommand[NIP_POS].substring(0, parsedCommand[NIP_POS].indexOf(NIP_DELIM)); 
   },

   
/*******************************************************************************
 * Parser for NAMERSERVER API command
 ******************************************************************************/
CustomParse_sysd_ns = function(line)
   {
   var regex = /\s*SYSD\s+NS\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/i;
   if(regex.test(line))
      {
      setting["sysd_ns"] = line.replace(regex, "$1");
      }
   },
   
CustomParse_sysd_profile = function(line)
   {
   /*
    * 
    response e.g:
      sysd profile list t1
      sysd profile list t2
      sysd profile list t3
      sysd profile list t4
   */
   var listRegex = /^\s*SYSD\s+PROFILE\s+LIST\s+(\w+)\s*/i;
   var statusRegex = /^\s*SYSD\s+PROFILE\s+STATUS\s+(\w+)\s*/i;
   if(!setting["sysd_profile"]){ setting["sysd_profile"] = {"list": [], "status": null};}
   
   if(listRegex.test(line))
      {
      setting["sysd_profile"].list.push({"name": line.replace(listRegex, "$1")});
      }
   else if(statusRegex.test(line))
      {
      setting["sysd_profile"].status = line.replace(statusRegex, "$1").toUpperCase();
      }
   
   },   

   
/********************************************
* Parser for stealth ip command
********************************************/
CustomParse_sysd_sip = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var SIP_POS = 3;
   var SIP_DELIM = ",";
   //gets the first argument of the response and removes the "," immediately after it
   //e.g 
   setting["sysd_sip"] = parsedCommand[SIP_POS].substring(0, parsedCommand[SIP_POS].indexOf(SIP_DELIM)); 
   },   

CustomParse_sysd_tp = function(line)
   {
//   e.g response 
//      sysd tp status 0
   var statusRegex = /\s*SYSD TP STATUS (\d+)/i;
   if(statusRegex.test(line))
      {
      setting["sysd_tp_status"] = parseInt(line.replace(statusRegex, "$1"), 10);
      }
   else
      {
      //log error
      }
   },

/*******************************************************************************
 * Parser for DCMD DIT
 ******************************************************************************/
CustomParse_dcmd_dit = function(line)
   {
   //gets the first argument of the response and removes the "," immediately after it
   //Response e.g DCMD DIT DECODERINPUT= RF1 1 
   var regex = /^\s*DCMD\s+DIT\s+DECODERINPUT=\s+(ASI|RF[12]|IP)\s+(\-*\d+)\s*/i;
   if(regex.test(line))
      {
      setting["dcmd_dit"] = 
         {
         "input": line.replace(regex, "$1"),
         "svcId": line.replace(regex, "$2")
         };
      }
   else
      {
      LogMyles("DCMD DIT Parse error");
      }
   },

/*******************************************************************************
 * Parser for device name command (terse)
 ******************************************************************************/
CustomParse_sysd_na = function(line)
   {
   var regex = /^\s*SYSD\s+NA\s+(.*)\s*/i;
   if(regex.test(line))
      {
      setting["sysd_na"] = line.replace(regex, "$1"); 
      }
   else
      {
      LogMyles("Regex Error in SYSD NA parser.");
      }
   },

/*******************************************************************************
 * Parser for device name command (verbose)
 ******************************************************************************/
CustomParse_sysd_nam = function(command)
   {
   var nameOffset = "SYSD NAM Name= ".length;
   //spaces are allowed..  Capture every character after the 15th character 
   setting["sysd_nam"] = command.substring(nameOffset); 
   },

/*******************************************************************************
 * Parser for time command
 ******************************************************************************/
CustomParse_sysd_tim = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var DATEPOS = 3;
   var TIMEPOS = 4;   
   //separates the response into date/time information
   setting["sysd_tim_date"] = ToMMDDYYYY(parsedCommand[DATEPOS]);
   setting["sysd_tim_time"] = parsedCommand[TIMEPOS]; 
   },

/*******************************************************************************
 * Parser for uptime command
 ******************************************************************************/
CustomParse_sysd_upt = function(command)
   {
   //captures everything after the "=" char on the response
   var DELIM = "=";
   var OFFSET = 2;
   setting["sysd_upt"] = command.substring(command.indexOf(DELIM)+OFFSET);
   },

/*******************************************************************************
 * Parser for SC (SCHEDULE)
 ******************************************************************************/
CustomParse_sysd_sc = function(command)
   {
   //command e.g
   //SYSD SC "/media/hd0/dvc/SCHtest.dvc"
   //SYSD SC Run= ON
   //SYSD SC Debug= ON
   //SYSD SC 0 event (s) in the schedule
   
   //SYSD SC "SCHEDULE NOT LOADED"
   //SYSD SC Run= ON
   //SYSD SC Debug= ON
   //SYSD SC 0 event (s) in the schedule
   
   var dvcFileRegex =      /^\s*SYSD\s+(SCHEDULER|SCH|SC)\s+"(([\w\/\s]*\w+\.dvc)|(SCHEDULE\s+NOT\s+LOADED))"\s*/i; 
   var runStatusRegex =    /^\s*SYSD\s+(SCHEDULER|SCH|SC)\s+RUN=\s+(ON|OFF)/i;
   var debugStatusRegex =  /^\s*SYSD\s+(SCHEDULER|SCH|SC)\s+DEBUG=\s+(ON|OFF)/i;
   var numEvtsRegex =      /^\s*SYSD\s+(SCHEDULER|SCH|SC)\s+(\d)\s+EVENT\s+\(S\)\s+IN\s+THE\s+SCHEDULE/i;
   if(dvcFileRegex.test(command))
      {
      var dvcFile = command.replace(dvcFileRegex, "$2");
      if(_SCH_NOT_LOADED_REGEX.test(dvcFile))
         {
         setting["sysd_sc_isLoaded"] = false;
         }
      else
         {
         setting["sysd_sc_isLoaded"] = true;
         setting["sysd_sc_dvcFile"] = dvcFile;      
         }
      }
   else if(runStatusRegex.test(command))
      {
      setting["sysd_sc_runStatus"] = command.replace(runStatusRegex, "$2");
      }
   else if(debugStatusRegex.test(command))
      {
      setting["sysd_sc_debugStatus"] = command.replace(debugStatusRegex, "$2");
      }
   else if(numEvtsRegex.test(command))
      {
      setting["sysd_sc_numEvents"] = parseInt(command.replace(debugStatusRegex, "$2"), _DEFAULT_NUM_BASE);
      }
       
   },

/*******************************************************************************
 * Custom Parser for DCMD DCB AOF Command. Response e.g:
 * 
 * DCMD AOF 0 PAIR0=100\r\n DCMD AOF 1 PAIR1=-25\r\n ... DCMD AOF 7
 * PAIR7=100\r\n \r\n
 * 
 ******************************************************************************/
CustomParse_dcmd_aof = function(line)
   {

      var regex;
      regex = /^DCMD AOF (\d+) PAIR\d+=(\-*\d+)$/i;

      if (regex.test(line))
         {
            setting["dcmd_aof_" + line.replace(regex, "$1")] = line.replace(
               regex, "$2");
         }
      else
         {
            LogMyles("Parse error in AOF API command.");
         }

   },

/*******************************************************************************
 * Custom Parser for DCMD DCB API Command. Response e.g:
 * 
 * DCMD DCB DecodeColorbars=OFF DCMD DCB DecodeColorbarsType=BARS
 * 
 ******************************************************************************/
CustomParse_dcmd_dcb = function (line)
   {
   var regex = /^DCMD DCB DecodeColorbars([Type]*)=(.*)/i;
   
   if(regex.test(line))
      {
      var key;
      
      if(line.replace(regex, "$1").length===0){ key = "mode";}
      else { key= "type";}

      setting["dcmd_dcb_" + key] = line.replace(regex, "$2").toUpperCase();
      }
   else
      {
      LogMyles("ERROR parsing DCMD DCB API command. Check Regex.");
      }
   },

/********************************************
 * Custom Parser for DCMD DCO API Command.  
 * Response e.g:
 * 
   DCMD DCO Osd Mode= OFF
   DCMD DCO Service Mode= OFF
   DCMD DCO Service Lines= 2
   DCMD DCO Service Blink= 0
   DCMD DCO X Position= 0
   DCMD DCO Y Position= 0
   DCMD DCO Text Size= 0X
   DCMD DCO String Format= 0
   DCMD DCO String Blink= OFF
   DCMD DCO String X Position= 0
   DCMD DCO String Y Position= 0
   DCMD DCO String Length= 0
   DCMD DCO String= 

 *
********************************************/
CustomParse_dcmd_dco = function(line)
   {
   var modeRegex = /^DCMD DCO Osd Mode=\s*(ON|OFF)/i;
   if(modeRegex.test(line))
      {
      setting["dcmd_dco"] = line.replace(modeRegex, "$1");
      }
   },

/*******************************************************************************
 * Custom Parser for DCMD DCT API Command. Response e.g:
 * 
 * DCMD DCT DecodeColorbarsTone= OFF DCMD DCT DecodeColorbarsChEnable= PAIR1=ON
 * PAIR2=ON PAIR3=ON PAIR4=ON PAIR5=ON PAIR6=ON PAIR7=ON PAIR8=ON DCMD DCT
 * DecodeColorbarsVolume= PAIR1=-20 dB PAIR2=-20 dB PAIR3=-20 dB PAIR4=-20 dB
 * PAIR5=-20 dB PAIR6=-20 dB PAIR7=-20 dB PAIR8=-20 dB DCMD DCT
 * DecodeColorbarsFreqLeft= PAIR1=1000 Hz PAIR2=1000 Hz PAIR3=1000 Hz PAIR4=1000
 * Hz PAIR5=1000 Hz PAIR6=1000 Hz PAIR7=1000 Hz PAIR8=1000 Hz DCMD DCT
 * DecodeColorbarsFreqRight= PAIR1=1000 Hz PAIR2=1000 Hz PAIR3=1000 Hz
 * PAIR4=1000 Hz PAIR5=1000 Hz PAIR6=1000 Hz PAIR7=1000 Hz PAIR8=1000 Hz DCMD
 * DCT DecodeColorbarsMuteLeft= PAIR1=OFF PAIR2=OFF PAIR3=OFF PAIR4=OFF
 * PAIR5=OFF PAIR6=OFF PAIR7=OFF PAIR8=OFF DCMD DCT DecodeColorbarsMuteRight=
 * PAIR1=OFF PAIR2=OFF PAIR3=OFF PAIR4=OFF PAIR5=OFF PAIR6=OFF PAIR7=OFF
 * PAIR8=OFF
 * 
 * 
 * 
 ******************************************************************************/
CustomParse_dcmd_dct = function(line)
   {
   var toneRegex,
      volRegex = /^$/,
      freqRegex = /^$/,
      muteRegex = /^$/,
      enRegex = /^$/,
      orientation, i;
   toneRegex = /^DCMD DCT DecodeColorbarsTone= (OFF|ON)$/i;

   var numAudioInputs = GetNumAudioInputs();

   switch (numAudioInputs) 
      {
      case 4:
         enRegex = /^DCMD DCT DecodeColorbarsChEnable= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON)$/i;
         volRegex = /^DCMD DCT DecodeColorbarsVolume= PAIR1=(\-*\d+) dB PAIR2=(\-*\d+) dB PAIR3=(\-*\d+) dB PAIR4=(\-*\d+) dB$/i;
         freqRegex = /^DCMD DCT DecodeColorbarsFreq(Left|Right)= PAIR1=(\d+) Hz PAIR2=(\d+) Hz PAIR3=(\d+) Hz PAIR4=(\d+) Hz$/i;
         muteRegex = /^DCMD DCT DecodeColorbarsMute(Left|Right)= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON)$/i;
         break;
      case 6:
         enRegex = /^DCMD DCT DecodeColorbarsChEnable= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON) PAIR5=(OFF|ON) PAIR6=(OFF|ON)$/i;
         volRegex = /^DCMD DCT DecodeColorbarsVolume= PAIR1=(\-*\d+) dB PAIR2=(\-*\d+) dB PAIR3=(\-*\d+) dB PAIR4=(\-*\d+) dB PAIR5=(\-*\d+) dB PAIR6=(\-*\d+) dB$/i;
         freqRegex = /^DCMD DCT DecodeColorbarsFreq(Left|Right)= PAIR1=(\d+) Hz PAIR2=(\d+) Hz PAIR3=(\d+) Hz PAIR4=(\d+) Hz PAIR5=(\d+) Hz PAIR6=(\d+) Hz$/i;
         muteRegex = /^DCMD DCT DecodeColorbarsMute(Left|Right)= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON) PAIR5=(OFF|ON) PAIR6=(OFF|ON)$/i;
         break;
      case 8:
         enRegex = /^DCMD DCT DecodeColorbarsChEnable= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON) PAIR5=(OFF|ON) PAIR6=(OFF|ON) PAIR7=(OFF|ON) PAIR8=(OFF|ON)$/i;
         volRegex = /^DCMD DCT DecodeColorbarsVolume= PAIR1=(\-*\d+) dB PAIR2=(\-*\d+) dB PAIR3=(\-*\d+) dB PAIR4=(\-*\d+) dB PAIR5=(\-*\d+) dB PAIR6=(\-*\d+) dB PAIR7=(\-*\d+) dB PAIR8=(\-*\d+) dB$/i;
         freqRegex = /^DCMD DCT DecodeColorbarsFreq(Left|Right)= PAIR1=(\d+) Hz PAIR2=(\d+) Hz PAIR3=(\d+) Hz PAIR4=(\d+) Hz PAIR5=(\d+) Hz PAIR6=(\d+) Hz PAIR7=(\d+) Hz PAIR8=(\d+) Hz$/i;
         muteRegex = /^DCMD DCT DecodeColorbarsMute(Left|Right)= PAIR1=(OFF|ON) PAIR2=(OFF|ON) PAIR3=(OFF|ON) PAIR4=(OFF|ON) PAIR5=(OFF|ON) PAIR6=(OFF|ON) PAIR7=(OFF|ON) PAIR8=(OFF|ON)$/i;
         break;

      case 2:
      case 16:
         // Placeholder. case not needed at the moment
         break;
      }
   if (toneRegex.test(line))
      {
      setting["dcmd_dct_tone"] = line.replace(toneRegex, "$1");
      }
   else if(enRegex.test(line))
      {
      for(i=0; i<numAudioInputs; i++)
         {
         setting["dcmd_dct_enabled_" + i] = (line.replace(enRegex, "$"+(i+1))=="ON")? true: false;
         }
      }
   else if(volRegex.test(line))
      {
      for(i=0; i<numAudioInputs; i++)
         {
         setting["dcmd_dct_vol" + i] = parseInt(line.replace(volRegex, "$"+(i+1)), 10);
         }
      }
   else if(freqRegex.test(line))
      {
      orientation = line.replace(freqRegex, "$1") + ""; //left or right.
      orientation = orientation.toLowerCase();
      var key = "dcmd_dct_freq_" + orientation;
      for(i=0; i<numAudioInputs; i++)
         {
         setting[key + "" + i] = line.replace(freqRegex, "$"+(i+2)); //offset by orientation placeholder
         }
      }
   else if(muteRegex.test(line))
      {
      orientation = line.replace(muteRegex, "$1") + ""; //left or right.
      orientation = orientation.toLowerCase();
      for(i=0; i<numAudioInputs; i++)
         {
         setting["dcmd_dct_mute_" + orientation + "" + i] = line.replace(muteRegex, "$"+(i+2)); //offset by orientation placeholder
         }
      }
   else
      {
      LogMyles("ERROR parsing DCMD DCT API Command. Check Regex.");
      }
   },

/*******************************************************************************
 * Parser for CFG command Input is in the form "DCMD CFG KEY=VALUE" e.g "DCMD
 * CFG VIDEO=1080I60"
 * 
 * Results in: "setting['dcmd_cfg_key']=VALUE" e.g "setting['dcmd_cfg_video'] =
 * 1080I60"
 ******************************************************************************/
CustomParse_dcmd_cfg = function(command)
   {

   var cfgRegex = /^\s*DCMD\s+CFG\s+((\w|_|)+)=((\w|\s|\.|\/)+)$/i;

   if (cfgRegex.test(command))
      {
      var KEYPOS = 1;
      var VALPOS = 3;
      var key = "dcmd_cfg_" + command.replace(cfgRegex, "$"+KEYPOS);
      var value = command.replace(cfgRegex, "$"+VALPOS);
      setting[key.toLowerCase()] = value;
      }
   else
      {
      LogMyles("Parse Error:  DCMD CFG line failed regex test.");
      }
   },

CustomParse_dcmd_d2 = function(line)
   {
   // line e.g  DCMD D2 0 0 1 0 2 0 0 10 10 10 1 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 00 00 00 00
   var regex = /^\s*DCMD\s+D2\s+\d+\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var regexPos = 
      {
      index:               1,      outformat:           2,      lefon:               3,
      compmode:            4,      stereooutmode:       5,      dualmonomode:        6,
      drscalehi:           7,      drscalelo:           8,      pcmscale:            9,
      errconceal:          10,     errblkrpt:           11,     substreamid:         12,
      dialnorm1:           13,     dialnorm2:           14,     acmod:               15,
      bsmod:               16,     bsid:                17,     streamtype:          18,
      audprodinfoexists0:  19,     audprodinfoexists1:  20,     mixlevel0:           21,
      mixlevel1:           22,     roomtype0:           23,     roomtype1:           24,
      copyright:           25,     original:            26,     surrmode:            27,
      surrexmode:          28,     adctype:             29,     timecodeexists:      30,
      tchour:              31,     tcmin:               32,     tcsec:               33,
      tcframe:             34,     tcframedec:          35
      };
   
   if(regex.test(line))
      {
      var index = parseInt(line.replace(regex, "$" + regexPos.index), 10);
      if(!setting["dcmd_d2"]){setting["dcmd_d2"]=[];}
      
      var o = {"outformat": parseInt(line.replace(regex, "$" + regexPos.outformat), 10)};
      setting["dcmd_d2"][index] =  o;
      
      }
   },
   
CustomParse_dcmd_da = function(line)
   {
   var daRegex = /^DCMD DA ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+) ([0x]*[0-9a-fA-F]+)\s*/i;
   setting["dcmd_da"] = []; //init array
   
   if(daRegex.test(line))
      {
      var daArr = [];
      for(var i=0; i<GetNumAudioInputs(); i++)
         {
         daArr[i] = HexToDec(line.replace(daRegex, "$"+(i+1)));
         }
      setting["dcmd_da"] = daArr; 
      }
   else
      {
      LogMyles("Parse Error. regex for DA Api command failed.");
      }
   },

/*******************************************************************************
 * Parser for INPUTTS API command
 ******************************************************************************/
CustomParse_dcmd_its = function(responseLine)
   {
//   response e.g
      /*
   DCMD ITS ASI 201 "TNT East" "Adtec Digital"
   DCMD ITS ASI 202 "Toon East" "Adtec Digital"
   DCMD ITS ASI 203 "TBS East" "Adtec Digital"
   DCMD ITS ASI 204 "Tru TV East" "Adtec Digital"
   DCMD ITS ASI 205 "CNN East" "Adtec Digital"
   DCMD ITS RF1 Services Unavailable
   DCMD ITS RF2 Services Unavailable
   DCMD ITS IP Services Unavailable
    */
   var INPUT_PORT_POS = 1, PGM_ID_POS =2, PGM_NAME_POS = 3, PGM_PROV_POS = 4, BIT_POS = 5;
   var regex = /^\s*DCMD\s+ITS\s+(ASI|RF1|RF2|IP)\s+(\d+)\s+"(.*)"\s+"(.*)"\s+(\d+)\-bit\s*/i;
   var naRegex = /^\s*DCMD\s+ITS\s+(ASI|RF1|RF2|IP)\s+SERVICES UNAVAILABLE\s*/i;
   if(naRegex.test(responseLine))
      {
     // Commented out to allow page load when condition exists. It is valid.
      //LogMyles("No available services for " + responseLine.replace(regex, "$"+INPUT_PORT_POS));
      }
   else if(regex.test(responseLine))
      {
      
      var port = responseLine.replace(regex, "$"+INPUT_PORT_POS);
      var pgmId = responseLine.replace(regex, "$"+PGM_ID_POS);
      var pgmName = responseLine.replace(regex, "$"+PGM_NAME_POS);
      var pgmProv = responseLine.replace(regex, "$"+PGM_PROV_POS);
      
      var obj = 
         {
         "port":        port,
         "pgm_id":      pgmId,
         "pgm_name":    pgmName,
         "pgm_prov":    pgmProv,
         "bit":         responseLine.replace(regex, "$"+BIT_POS)
         };
      
      if((setting["dcmd_its"]===undefined) || (setting["dcmd_its"] === null)){setting["dcmd_its"] = [];} //init array if it doesn't exist
      
      setting["dcmd_its"].push(obj); //add new object to created array
      
      }
   else
      {
      LogMyles("Error in DCMD ITS parser.");
      }
   
   },

/*******************************************************************************
 * Parser for DECODESERVICE API command
 ******************************************************************************/
CustomParse_dcmd_decodeservice = function(line)
   {
   //response e.g
   /*
    DCMD DECODESERVICE ASI 201 "TNT East" "Adtec Digital"
   */
   var result = null;
      
   var dsRegex =  /^\s*DCMD\s+DECODESERVICE\s+(ASI|RF1|RF2|IP)\s+(\d+)\s+"(.*)"\s+"(.*)"\s*/i;
   var dsnaRegex = /^\s*DCMD\s+DECODESERVICE\s+No active services found\s*/i;
   
   
   if(dsnaRegex.test(line))
      {
      result = 
         {
         "enabled":        false,
         "port":           "--N/A--",
         "number":         -1,
         "name":           "--N/A--",
         "provider":       "--N/A--"
         };
      }
   else if (dsRegex.test(line))
      {
      result = 
         {
         "enabled":        true,
         "port":           line.replace(dsRegex, "$1"),
         "number":         parseInt(line.replace(dsRegex, "$2"), 10),
         "name":           line.replace(dsRegex, "$3"),
         "provider":       line.replace(dsRegex, "$4")
         };
      }
   else
      {
      LogMyles("DCMD DECODESERVICE LOCAL PARSE ERROR.");
      }
   setting["dcmd_decodeservice"] = result;
   },
   

/********************************************
* Parser for track selection command
********************************************/   
 
CustomParse_dcmd_tsn = function(command)
   {
   var KEYWORD_POS = 2;
   var KEYWORD_STR = "TRACKSELECT="; 
   var TSN_POS = 3;     
   var parsedCommand = ParseCommand( command, ' ' );
   //tsn response commes in separate lines, where only one of them is relevant..  
   if(parsedCommand[KEYWORD_POS]==KEYWORD_STR) //identify if this is a relevant line
      {
      setting["dcmd_tsn"] = parseInt(parsedCommand[TSN_POS], _DEFAULT_NUM_BASE);
      }
   },

/***************************************************
* Parser for terse version of Audio Offset command
***************************************************/
CustomParse_dcmd_uo = function(line)
   {
   //line e.g: DCMD UO 1 2 3 4 5 6 7 8
   var regex = /^\s*DCMD\s+UO\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s*/i;
   if((setting["dcmd_uo"]===undefined) || (setting["dcmd_uo"]===null)){setting["dcmd_uo"] = [];} //Init if object has not been initialized
   if(regex.test(line))
      {
      var i=0, uoArr = [];
      for(; i<GetNumAudioInputs(); i++)
         {
         uoArr[i] =  parseInt(line.replace(regex, "$"+(i+1)), 10);
         }
      setting["dcmd_uo"] = uoArr;
      }
   else
      {
      LogMyles("Error in parser for DCMD UO");
      }
   
   },
/***************************************************
* Parser for terse version of US command
***************************************************/
CustomParse_dcmd_us = function(line)
   {
   var decrypt_valid, sbs;
   /* 
    * Default:
    * DCMD US [STATUS] [SOURCE] [SOURCE_STATUS] [PROGRAM] [PCR] [PMT] [STC]
    * Response e.g:  DCMD US 2 0 2 1 1e1 1e0 97828809
    */
   var defaultRegex = /^\s*DCMD\s+US\s+(\d+)\s+(\d+)\s+(\d+)\s+(\-*\d+)\s+([0x]*[0-9a-fA-F]+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)*/i;
   var DEF_POS =  {  "status": 1, "src": 2, "src_status": 3, "pgm": 4, "pcr": 5, "pmt":6, "stc": 7, "input_tmr": 8, "video_tmr": 9, "delay_mode": 10, "decode_delay": 11};

   /*
    * video:
    * DCMD US VIDEO [PID] [HRES] [VRES] [FRATE] [STREAM_TYPE] [CHROMA] [BIT_RATE] [SCRAMBLE_BITS_SET] [DECRYPT_VALID]
    * Response e.g: 1e1 1920 1088 29.97i 27 2 417583
    */ 
   var videoRegex =   /^\s*DCMD\s+US\s+VIDEO\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+(\d+)\s+([\d|\.]+[i|p]*)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var noVideoRegex = /^\s*DCMD\s+US\s+VIDEO\s+(\d+)\s+(\d+)\s+(\d+)\s+([0-1][ip]*)\s+([0-1])\s+([0-1])\s+([0-1])\s+([0-1])\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;   
   var VID_POS =  {  "pid": 1, "hsize": 2, "vsize": 3, "frate": 4, "streamtype": 5, "chroma": 6, "bitrate": 7, 
            "scramble_bits_set": 8, "decrypt_valid": 9, "bit_depth": 10, "delay_mode": 11, "decode_delay": 12 };

   /*
    * Audio:
    * DCMD US AUDIO [IDX] [PID] [STREAM_TYPE] [DECODE_STATUS] [BIT_RATE] [SAMPLE_RATE] [CHANNEL_MODE] [SCRAMBLE_BITS_SET] [DECRYPT_VALID] 
    * e.g: DCMD US AUDIO 0 1e2 22 0 1068 19984 19972
    */ 
   var audioRegex = /^\s*DCMD\s+US\s+AUDIO\s+(\d+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var AUD_POS =  {  "idx": 1, "pid": 2, "streamtype": 3, "dec_status": 4, "bitrate": 5, "sample_rate": 6, "ch_mode":7, "scramble_bits_set": 8, "decrypt_valid": 9, "offset": 10 };

   /*
    * Passthru:
    * DCMD US PASSTHRU [INDEX] [TYPE] [ACTIVE] [FIFO_PKTS] [DOLBY_E_CURR_LINE] [DOLBY_E_PTS_DETECTION_LINE] [UNDERFLOW] [NUM_RESETS] [PID] [SYNC_OFFSET] [SDI_CHANNEL_PAIR] [SCRAMBLE_BITS_SET] [DECRYPT_VALID] [DELAY_MS] [NUM_AUTO_RESETS] 
    */ 
   var passthruRegex = /^\s*DCMD\s+US\s+PASSTHRU\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var PST_POS =  
      {  
      "idx": 1, "type": 2, "active": 3, "fifo_pkts":   4, "de_curr_line": 5, "de_pts_detect_line": 6, "underflow":7, "num_resets": 8, 
      "pid": 9, "sync_offset": 10, "sdi_ch_pair": 11, "scramble_bits_set": 12, "decrypt_valid": 13, "delay": 14, "num_auto_resets": 15,
      "offset_cfg": 16, "offset_avg": 17, "sample_bits": 18, "bitrate_tmr": 19, "mute": 20, "no_dolbye_hdr": 21, "header_error": 22,
      "pass_av_sync_reset": 23
      };
   
   if(setting["dcmd_us"]===undefined)
      {//init object if this is the first time this parser is being invoked
      setting["dcmd_us"] = 
         {
         "BASIC": null,
         "VIDEO": null, 
         "AUDIO": null, 
         "PASSTHRU": null
         };
      
      }
   if(defaultRegex.test(line))
      {
      var trstatus, status, src, src_status, pgm, pcr, pmt, stc, videoTmr, inputTmr ;
      // added terse version for light indicators...may be a better way ~ ahp
      trstatus = parseInt(line.replace(defaultRegex, "$"+DEF_POS.status), 10);
      status = GetDecoderStatus(parseInt(line.replace(defaultRegex, "$"+DEF_POS.status), 10));
      src =    GetDecoderSource(parseInt(line.replace(defaultRegex, "$"+DEF_POS.src), 10));
      src_status = GetDecoderSourceStatus(parseInt(line.replace(defaultRegex, "$"+DEF_POS.src_status), 10));
      pgm = parseInt(line.replace(defaultRegex, "$"+DEF_POS.pgm), 10);
      pcr = line.replace(defaultRegex, "$"+DEF_POS.pcr); //Hex
      pmt = line.replace(defaultRegex, "$"+DEF_POS.pmt); //Hex
      stc = parseInt(line.replace(defaultRegex, "$"+DEF_POS.stc), 10);
      inputTmr = parseInt(line.replace(defaultRegex, "$"+DEF_POS.input_tmr), 10);
      videoTmr = parseInt(line.replace(defaultRegex, "$"+DEF_POS.video_tmr), 10);
      
      if(src!==null)
         { 
         if(setting["dcmd_us"].BASIC===null){ setting["dcmd_us"].BASIC = {}; } //init object
         setting["dcmd_us"].BASIC.source = src;
         setting["dcmd_us"].BASIC.trstatus = trstatus;
         setting["dcmd_us"].BASIC.status = status;
         setting["dcmd_us"].BASIC.src_status = src_status;
         setting["dcmd_us"].BASIC.pgmNo = pgm;
         setting["dcmd_us"].BASIC.pcr = pcr;
         setting["dcmd_us"].BASIC.pmt = pmt;
         setting["dcmd_us"].BASIC.stc = stc;
         setting["dcmd_us"].BASIC.input_tmr = inputTmr;
         setting["dcmd_us"].BASIC.video_tmr = videoTmr;
//         setting["dcmd_us"].BASIC.delay_mode = parseInt(line.replace(defaultRegex, "$"+DEF_POS.delay_mode), 10);
//         setting["dcmd_us"].BASIC.decode_delay = parseInt(line.replace(defaultRegex, "$"+DEF_POS.decode_delay), 10);
         }
      else 
         {
         LogMyles("DCMD US Parse Error.  Unknown source.");
         }
      }
   
   else if(videoRegex.test(line))
      {
      if(setting["dcmd_us"].VIDEO   ===null){ setting["dcmd_us"].VIDEO = {}; } //init object

      if(noVideoRegex.test(line))
         {
         setting["dcmd_us"].VIDEO.pid =         '--N/A--';
         setting["dcmd_us"].VIDEO.frame_rate =  '--N/A--';
         setting["dcmd_us"].VIDEO.viStrType =   '--N/A--';
         setting["dcmd_us"].VIDEO.chroma =      0;
         setting["dcmd_us"].VIDEO.bitRate =     '--N/A--';
         setting["dcmd_us"].VIDEO.resolution =  '--N/A--';
         setting["dcmd_us"].VIDEO.scramble_bits_set =   (parseInt(line.replace(noVideoRegex, "$"+VID_POS.scramble_bits_set), 10)===0)? false: true;
         setting["dcmd_us"].VIDEO.decrypt_valid =          (_DECRYPTSTATUSARRAY.length - 1);
         setting["dcmd_us"].VIDEO.bit_depth =  '--N/A--';
         setting["dcmd_us"].VIDEO.delay_mode =  '--N/A--';
         setting["dcmd_us"].VIDEO.decode_delay =  '--N/A--';
         }
      else
         { //regular video
         var pid, hSize, vSize, fRate, viStrType, chroma, bitRate ;
         pid = HexToDec(line.replace(videoRegex, "$"+VID_POS.pid)); //Hex
         hSize = parseInt(line.replace(videoRegex, "$"+VID_POS.hsize), 10);
         vSize = parseInt(line.replace(videoRegex, "$"+VID_POS.vsize), 10);
         fRate = line.replace(videoRegex, "$"+VID_POS.frate); //
         viStrType = parseInt(line.replace(videoRegex, "$"+VID_POS.streamtype), 10);
         chroma = parseInt(line.replace(videoRegex, "$"+VID_POS.chroma), 10);
         bitRate = parseInt(line.replace(videoRegex, "$"+VID_POS.bitrate), 10);
         sbs = (parseInt(line.replace(videoRegex, "$"+VID_POS.scramble_bits_set), 10)===0)? false: true;
         decrypt_valid = parseInt(line.replace(videoRegex, "$"+VID_POS.decrypt_valid), 10);
         
         setting["dcmd_us"].VIDEO.pid =         pid;
         setting["dcmd_us"].VIDEO.hsize =       hSize;
         setting["dcmd_us"].VIDEO.vsize =       vSize;
         setting["dcmd_us"].VIDEO.frame_rate =  fRate;
         setting["dcmd_us"].VIDEO.stream_type =   viStrType;
         setting["dcmd_us"].VIDEO.chroma =      chroma;
         setting["dcmd_us"].VIDEO.bitRate =     bitRate;
         setting["dcmd_us"].VIDEO.resolution =  hSize + "x" + vSize;
         setting["dcmd_us"].VIDEO.scramble_bits_set =          sbs;
         setting["dcmd_us"].VIDEO.decrypt_valid =          decrypt_valid;
         setting["dcmd_us"].VIDEO.bit_depth = parseInt(line.replace(videoRegex, "$"+VID_POS.bit_depth), 10);//tmp
         setting["dcmd_us"].VIDEO.delay_mode =  parseInt(line.replace(videoRegex, "$"+VID_POS.delay_mode), 10);
         setting["dcmd_us"].VIDEO.decode_delay =  parseInt(line.replace(videoRegex, "$"+VID_POS.decode_delay), 10);
         
         }
      }
   else if(audioRegex.test(line))
      {
      var idx, auPid, auStrType, decStatus, auBitRate, sampleRate, chMode;
      
      if(setting["dcmd_us"].AUDIO ===null){ setting["dcmd_us"].AUDIO = []; } //init array
      idx = parseInt(line.replace(audioRegex, "$"+AUD_POS.idx), 10);
      if(isNaN(idx))
         {
         LogMyles("DCMD US Parse Error:  Invalid Audio Index."); 
         return;
         }
      auPid = parseInt(line.replace(audioRegex, "$"+AUD_POS.pid), 10);
      auStrType = GetStreamType(parseInt(line.replace(audioRegex, "$"+AUD_POS.streamtype), 10));
      decStatus = GetDecoderAudioStatus(parseInt(line.replace(audioRegex, "$"+AUD_POS.dec_status), 10));
      auBitRate = parseInt(line.replace(audioRegex, "$"+AUD_POS.bitrate), 10);
      sampleRate = parseInt(line.replace(audioRegex, "$"+AUD_POS.sample_rate), 10);
      chMode = parseInt(line.replace(audioRegex, "$"+AUD_POS.ch_mode), 10);
      sbs = (parseInt(line.replace(audioRegex, "$"+AUD_POS.scramble_bits_set), 10)===0)?false: true;
      decrypt_valid = parseInt(line.replace(audioRegex, "$"+AUD_POS.decrypt_valid), 10);
      
      setting["dcmd_us"].AUDIO[idx] = {}; //init or re-init object
      setting["dcmd_us"].AUDIO[idx].pid = auPid;
      setting["dcmd_us"].AUDIO[idx].streamType = auStrType;
      setting["dcmd_us"].AUDIO[idx].decStatus = decStatus;
      setting["dcmd_us"].AUDIO[idx].bitrate = auBitRate;
      setting["dcmd_us"].AUDIO[idx].sampleRate = sampleRate;
      setting["dcmd_us"].AUDIO[idx].chMode = chMode;
      setting["dcmd_us"].AUDIO[idx].scramble_bits_set = sbs;
      setting["dcmd_us"].AUDIO[idx].decrypt_valid = decrypt_valid;
      }
   else if(passthruRegex.test(line))
      {
      if(setting["dcmd_us"].PASSTHRU ===null){ setting["dcmd_us"].PASSTHRU = []; } //init array
      var ptIdx, type, active, fifo_pkts, dolbyECurrLine, dolbyEPtsDetecLine, underflow, numResets, ptPid, syncOffset, sdiChPair, delay, num_auto_resets;
      
      ptIdx = parseInt(line.replace(passthruRegex, "$"+PST_POS.idx), 10);
      if(isNaN(ptIdx))
         {
         LogMyles("DCMD US Parse Error:  Invalid Passthru Index.");
         return;
         }
      type = parseInt(line.replace(passthruRegex, "$"+PST_POS.type), 10);
      active = parseInt(line.replace(passthruRegex, "$"+PST_POS.active), 10);
      fifo_pkts = parseInt(line.replace(passthruRegex, "$"+PST_POS.fifo_pkts), 10);
      dolbyECurrLine = parseInt(line.replace(passthruRegex, "$"+PST_POS.de_curr_line), 10);
      dolbyEPtsDetecLine = parseInt(line.replace(passthruRegex, "$"+PST_POS.de_pts_detect_line), 10);
      underflow = parseInt(line.replace(passthruRegex, "$"+PST_POS.underflow), 10);
      numResets = parseInt(line.replace(passthruRegex, "$"+PST_POS.num_resets), 10);
      ptPid = parseInt(line.replace(passthruRegex, "$"+PST_POS.pid), 10); 
      syncOffset = parseInt(line.replace(passthruRegex, "$"+PST_POS.sync_offset), 10);
      sdiChPair = parseInt(line.replace(passthruRegex, "$"+PST_POS.sdi_ch_pair), 10);
      sbs = (parseInt(line.replace(passthruRegex, "$"+PST_POS.scramble_bits_set), 10)===0)?false: true;
      decrypt_valid = parseInt(line.replace(passthruRegex, "$"+PST_POS.decrypt_valid), 10);
      delay = parseInt(line.replace(passthruRegex, "$"+PST_POS.delay), 10);
      num_auto_resets = parseInt(line.replace(passthruRegex, "$"+PST_POS.num_auto_resets), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx] = {};
      setting["dcmd_us"].PASSTHRU[ptIdx].type = type;
      setting["dcmd_us"].PASSTHRU[ptIdx].active = (active===0)? false: true;
      setting["dcmd_us"].PASSTHRU[ptIdx].fifo_pkts = fifo_pkts;
      setting["dcmd_us"].PASSTHRU[ptIdx].dolbyECurrLine = dolbyECurrLine;
      setting["dcmd_us"].PASSTHRU[ptIdx].dolbyEPtsDetecLine = dolbyEPtsDetecLine;
      setting["dcmd_us"].PASSTHRU[ptIdx].underflow = underflow;
      setting["dcmd_us"].PASSTHRU[ptIdx].numResets = numResets;
      setting["dcmd_us"].PASSTHRU[ptIdx].ptPid = ptPid;
      setting["dcmd_us"].PASSTHRU[ptIdx].syncOffset = syncOffset;
      setting["dcmd_us"].PASSTHRU[ptIdx].sdiChPair = sdiChPair;
      setting["dcmd_us"].PASSTHRU[ptIdx].scramble_bits_set = sbs;
      setting["dcmd_us"].PASSTHRU[ptIdx].decrypt_valid = decrypt_valid;
      setting["dcmd_us"].PASSTHRU[ptIdx].delay = delay;
      setting["dcmd_us"].PASSTHRU[ptIdx].num_auto_resets = num_auto_resets;
      
      setting["dcmd_us"].PASSTHRU[ptIdx].offset_cfg = parseInt(line.replace(passthruRegex, "$"+PST_POS.offset_cfg), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].offset_avg = parseInt(line.replace(passthruRegex, "$"+PST_POS.offset_avg), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].sample_bits = parseInt(line.replace(passthruRegex, "$"+PST_POS.sample_bits), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].bitrate_tmr = parseInt(line.replace(passthruRegex, "$"+PST_POS.bitrate_tmr), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].mute = parseInt(line.replace(passthruRegex, "$"+PST_POS.mute), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].no_dolbye_hdr = parseInt(line.replace(passthruRegex, "$"+PST_POS.no_dolbye_hdr), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].header_error = parseInt(line.replace(passthruRegex, "$"+PST_POS.header_error), 10);
      setting["dcmd_us"].PASSTHRU[ptIdx].pass_av_sync_reset = parseInt(line.replace(passthruRegex, "$"+PST_POS.pass_av_sync_reset), 10);
      
      }
   else 
      {
      LogMyles("DCMD US Parse Error. Line: \"" + line + "\"");
      }
   },
   
/********************************************
* Parser for output video scale
********************************************/   
 
CustomParse_dcmd_ovs = function(command)
   {
   var
    OFFPOS = 3,
    OFFSTR = "OFF",
    POSITION_POS = 4,
    WIDTH_HEADER_POS = 6,
    WIDTH_DELIM_CHAR = "W",
    HEIGHT_HEADER_POS = 8,
    HEIGHT_DELIM_CHAR = "H",
    ASPECT_HEADER_STR = "(Aspect",
    AUTO_KW_STR = "AUTO",
    WIDTH_HEIGHT_SEPARATOR = " X ",
    NON_ASPECT_HEIGHT_POS = 11
    ;
    
    
   var width, height;
   var parsedCommand = ParseCommand( command, ' ' );
   if(parsedCommand[OFFPOS]==OFFSTR) 
      { 
      setting["dcmd_ovs_position"] = "Native";
      setting["dcmd_ovs_size"] = "Native";
      }
   else
      {
      setting["dcmd_ovs_position"] = parsedCommand[POSITION_POS];
      if(parsedCommand[WIDTH_HEADER_POS]!=ASPECT_HEADER_STR)
         {
         width =  parsedCommand[WIDTH_HEADER_POS].substring(0, parsedCommand[WIDTH_HEADER_POS].indexOf(WIDTH_DELIM_CHAR));
         
         if(parsedCommand[HEIGHT_HEADER_POS]!=ASPECT_HEADER_STR)
            {
            height = parsedCommand[HEIGHT_HEADER_POS].substring(0, parsedCommand[HEIGHT_HEADER_POS].indexOf(HEIGHT_DELIM_CHAR));
            }
         else
            {
            height = AUTO_KW_STR;
            }
         
         }
      else  
         { 
         width = AUTO_KW_STR;
         height = parsedCommand[NON_ASPECT_HEIGHT_POS].substring(0, parsedCommand[NON_ASPECT_HEIGHT_POS].indexOf(HEIGHT_DELIM_CHAR)); 
         }
      
      
      setting["dcmd_ovs_size"] = width + WIDTH_HEIGHT_SEPARATOR + height;
      }
   },

/*******************************************************************************
 * Parser for decoder program number
 ******************************************************************************/
CustomParse_dcmd_dpn = function(command)
   {
   //e.g:
   //DCMD DPN Program Number 1(0x1) Pid 0x64
   //DCMD DPN  Vid_MPEG2_SD Pid 0x65
   //DCMD DPN  Unknown Pid 0x66
   //DCMD DPN  Unknown Pid 0x67
   //DCMD DPN ACTIVE Program Number 1(0x1) Pid 0x64
   //DCMD DPN ACTIVE  Vid_MPEG2_SD Pid 0x65
   //DCMD DPN ACTIVE  Unknown Pid 0x66
   //DCMD DPN ACTIVE  Unknown Pid 0x67
       
   var activeRegex = /^\s*DCMD\s+DPN\s+ACTIVE\s+.*/i;
   var progPresentRegex = /\s+PROGRAM\s+NUMBER\s+(\d+)/i; 
   var fullProgPresentRegex = /^.*PROGRAM\s+NUMBER\s+(\d+).*/i;
   var noPgmsActiveRegex = /NOT\s+ACTIVE\s+OR\s+TUNING/i;
   if(activeRegex.test(command))
      {// e.g: DCMD DPN ACTIVE .... 
      if(progPresentRegex.test(command))
         {//e.g: DCMD DPN ACTIVE Program Number 1(0x1) Pid 0x64
         setting["dcmd_dpn_active"] = command.replace(fullProgPresentRegex, "$1");
         setting["dcmd_dpn_isActive"] = true;
         }
      else if(noPgmsActiveRegex.test(command))
         { //e.g: DCMD DPN ACTIVE Not Active or Tuning
         setting["dcmd_dpn_isActive"] = false;
         }
      }
   else if(progPresentRegex.test(command))
      { // DCMD DPN ....
      if ((setting["dcmd_dpn_elements"] === null)||(setting["dcmd_dpn_elements"] === undefined))
         {//e.g: DCMD DPN Program Number 1(0x1) Pid 0x64
         setting["dcmd_dpn_elements"] = [];
         _programIndex = 0;         
         }
      setting["dcmd_dpn_elements"][_programIndex++] = command.replace(fullProgPresentRegex, "$1");  
      }
   else if(noPgmsActiveRegex.test(command))
      {  //e.g: DCMD DPN Not Active or Tuning
      setting["dcmd_dpn_elements"] = [];
      _programIndex = 0;
      }  
      
   },

//      
// /********************************************
// * Parser for decoder status.
// ********************************************/
// CustomParse_dcmd_dus = function(line)
// {
// //e.g:
// // DCMD DUS ASI 201 PROGRAM=000201 VIDEO_PID=0x01e1
// VIDEO_STREAMTYPE=ISO_IEC_13818_VIDEO VIDEO_CHROMA=420 VIDEO_BITRATE=7068215
// // DCMD DUS ASI 201 AUDIO_INDEX=0 AUDIO_DECODE_STATUS=00 AUDIO_PID=0x01e2
// AUDIO_STREAMTYPE=MPEG1_Layer2 AUDIO_CHANNEL_MODE=0000
// AUDIO_SAMPLE_RATE=000000 AUDIO_BITRATE=000000
// // DCMD DUS ASI 201 AUDIO_INDEX=1 AUDIO_DECODE_STATUS=00 AUDIO_PID=000000
// AUDIO_STREAMTYPE=UNKNOWN AUDIO_CHANNEL_MODE=0000 AUDIO_SAMPLE_RATE=000000
// AUDIO_BITRATE=000000
// // DCMD DUS ASI 201 AUDIO_INDEX=2 AUDIO_DECODE_STATUS=00 AUDIO_PID=000000
// AUDIO_STREAMTYPE=UNKNOWN AUDIO_CHANNEL_MODE=0000 AUDIO_SAMPLE_RATE=000000
// AUDIO_BITRATE=000000
// // DCMD DUS ASI 201 AUDIO_INDEX=3 AUDIO_DECODE_STATUS=00 AUDIO_PID=000000
// AUDIO_STREAMTYPE=UNKNOWN AUDIO_CHANNEL_MODE=0000 AUDIO_SAMPLE_RATE=000000
// AUDIO_BITRATE=000000
//       
// var videoRegex = /^DCMD DUS (ASI|RF1|RF2|IP) (\d+) PROGRAM=(\d+)
// VIDEO_PID=([0x]*[\da-fA-F]+) VIDEO_STREAMTYPE=(\w+) VIDEO_CHROMA=(\d+)
// VIDEO_BITRATE=(\d+)$/i;
// var audioRegex = /^DCMD DUS (ASI|RF1|RF2|IP) (\d+) AUDIO_INDEX=(\d+)
// AUDIO_DECODE_STATUS=(\d+) AUDIO_PID=([0x]*[0-9a-fA-F]+)
// AUDIO_STREAMTYPE=(\w+) AUDIO_CHANNEL_MODE=([0x]*[0-9a-fA-F]+)
// AUDIO_SAMPLE_RATE=(\d+) AUDIO_BITRATE=(\d+)$/i;
// var inputType, svcId, keyPrefix, audioIdx;
//   
// if(videoRegex.test(line))
// {
// inputType = line.replace(videoRegex, "$1");
// svcId = parseInt(line.replace(videoRegex, "$2"), 10);
// // svcId = line.replace(videoRegex, "$2");
// keyPrefix = "dcmd_dus_" + inputType.toLowerCase() + "_" + svcId + "_video_";
// setting[keyPrefix + "pid"] = line.replace(videoRegex, "$4");
// setting[keyPrefix + "stream_type"] = line.replace(videoRegex, "$5");
// setting[keyPrefix + "chroma"] = line.replace(videoRegex, "$6");
// setting[keyPrefix + "bitrate"] = line.replace(videoRegex, "$7");
// }
// else if(audioRegex.test(line))
// {
// inputType = line.replace(audioRegex, "$1");
// svcId = parseInt(line.replace(audioRegex, "$2"), 10);
// keyPrefix = "dcmd_dus_" + inputType.toLowerCase() + "_" + svcId + "_audio_";
//   
// audioIdx = parseInt(line.replace(audioRegex, "$3"), 10);
//         
// setting[keyPrefix + audioIdx + "_decode_status"] = line.replace(audioRegex,
// "$4");
// setting[keyPrefix + audioIdx + "_pid"] = line.replace(audioRegex, "$5");
//      
// setting[keyPrefix + audioIdx + "_stream_type"] = line.replace(audioRegex,
// "$6");
// setting[keyPrefix + audioIdx + "_channel_mode"] =
// parseInt(line.replace(audioRegex, "$7"), 10);
// setting[keyPrefix + audioIdx + "_sample_rate"] =
// parseInt(line.replace(audioRegex, "$8"), 10);
// setting[keyPrefix + audioIdx + "_bitrate"] =
// parseInt(line.replace(audioRegex, "$9"), 10);
//        
// if((setting[keyPrefix + "max_idx"] === undefined) || (setting[keyPrefix +
// "max_idx"] < audioIdx))
// {//update the max audio index for the service
// setting[keyPrefix + "max_idx"] = audioIdx;
// }
//
// }
// else
// {
// LogMyles("CustomParse_dcmd_dus parse error");
// }
//      
// },

/*******************************************************************************
 * Parser for TR (TRANSPORT) command of the decoder
 ******************************************************************************/
CustomParse_dcmd_tr = function(command)
   {
   //e.g response
   //DCMD TR 01 "/mnt/hd/media/nestle.mpg"                                                   0011286  00 00 30 009 030     08 08 96       06    20 00 00 00 00    00 00 \r\n
   //DVB-ASI RECEIVING e.g
   //DCMD TR 20 "Pgm_1_Pid0x30 Vid_MPEG2_HD_Pid0x31 Aud_MPEG_L2_Pid0x34 Aud_MPEG_L2_Pid0x35" 00       00 00 00 000 0000000 00 00 0000     000   00 00 00 19 004   00 00
   //MULTICASTRECEIVING e.g
   //DCMD TR 15 "226.0.1.1:2000"                                                             00       00 00 00 000 0001984 00 00 0000     000   00 00 00 41 348   00 00
   //DCMD TRA PLAYING MULTICAST RECEIVING Group = 226.0.1.1 Port = 2000 000.00 MBytes --:--:--.--- 2.49 Mbps 00/00/0000 00:00 00:03:09.957  00.00%
     
   var DCMDTRREGEXPOS = 
      {
      "STATUS":               1, 
      "PGINFO":               2,
      "SIZE":                 3,
      "HOUR":                 4,
      "MINUTE":               5,
      "SECOND":               6,
      "MSEC":                 7,
      "RATE":                 8,
      "MONTH":                9,
      "DAY":                  10,
      "YEAR":                 11,
      
      "UPTH":                 14,
      "UPTM":                 15,
      "UPTS":                 16,
      "UPTMS":                17,
      "PROGRESSPCT":          18,
      "PROGRESSPCTDEC":       19
      };
   var MAXPGINFOLEN = 32;
   //dcmd tr 15 "226.0.1.1:2000" 00 00 00 00 000 0002458 00 00 0000 000 00 00 58 13 343 00 00
   
   var regex = /^\s*DCMD\s+TR\s+(\d{1,2})\s+"{1,2}([\w\s\.\/:\-]+)"{1,2}\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   
   if(regex.test(command))
      {
      setting["dcmd_tr_decodeStatus"] =   GetDecodeStatus(command.replace(regex, "$"+DCMDTRREGEXPOS.STATUS)); //get status
      setting["dcmd_tr_decodeImage"] =    GetDecodeImage (command.replace(regex, "$"+DCMDTRREGEXPOS.STATUS)); //get led image
      setting["dcmd_tr_pginfo"] = command.replace(regex, "$"+DCMDTRREGEXPOS.PGINFO);
      if(setting["dcmd_tr_pginfo"].length>MAXPGINFOLEN)
         {
         setting["dcmd_tr_pginfo"] = setting["dcmd_tr_pginfo"].substring(0, (MAXPGINFOLEN - "...".length)) + "...";
         }
       
      setting["dcmd_tr_rate"] = (parseInt(command.replace(regex, "$"+DCMDTRREGEXPOS.RATE), _DEFAULT_NUM_BASE)/_KBITSPERMBITS);
      setting["dcmd_tr_progress"] = parseFloat(command.replace(regex, "$"+DCMDTRREGEXPOS.PROGRESSPCT) + "." + command.replace(regex, "$"+DCMDTRREGEXPOS.PROGRESSPCTDEC), _DEFAULT_NUM_BASE) ;
      setting["dcmd_tr_uptime"] =  
      command.replace(regex, "$"+DCMDTRREGEXPOS.UPTH) + _TIME_DELIM + 
      command.replace(regex, "$"+DCMDTRREGEXPOS.UPTM) + _TIME_DELIM +
      command.replace(regex, "$"+DCMDTRREGEXPOS.UPTS) + "." +
      command.replace(regex, "$"+DCMDTRREGEXPOS.UPTMS);      
      }
   else
      {
      LogMyles("DCMD TR Parser error.  Regular expression did not match response");
      }
   },

/*******************************************************************************
 * Parser for LI (LIST) command of the decoder
 ******************************************************************************/
CustomParse_dcmd_li = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var temp = parsedCommand[2];
   
   if(temp.indexOf(_SMIL_EXT_STR)!=-1) //playlist found
      {
      setting["dcmd_li_list"] = temp.substring(1, temp.lastIndexOf('"')); //remove quotation marks
      }
       
   },
   
/************************************************** 
* Parser for terse MK command of the decoder
**************************************************/
CustomParse_dcmd_mk = function(line)
   {
   var regex = /\s*DCMD\s+MK\s+(\d+)\s+(\d+)\s*/i;
   if(setting["dcmd_mk"]===undefined)      {      setting["dcmd_mk"] = [];      }
   if(regex.test(line))
      {
      setting["dcmd_mk"][parseInt(line.replace(regex, "$1"), 10)] = parseInt(line.replace(regex, "$2"), 10); 
      }
   else
      {//highly unlikely.
      LogMyles("Parse Error in DCMD MK.  Check regex.");
      }
   },
/************************************************** 
* Parser for terse SERVICEINFO SNF NF command of the decoder
**************************************************/
CustomParse_dcmd_nf = function(line)
   {
   /*
    *  Response  "DCMD NF 0 1 1e0 1e1 0 1e1 27 1 2147483647 1920 1088 25i 0 0 8"
    */    
   var regex = /^\s*DCMD\s+NF\s+(\d+)\s+(\d+)\s+([0x]*[0-9a-fA-F]+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d|\.]+[i|p]*)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var naRegex = /^\s*DCMD\s+NF\s+(\d+)\s+No Services Available\s*/i;

   if(setting["dcmd_nf"]===undefined)
      {
      setting["dcmd_nf"] = {  "ASI": null,   "RF1": null,   "RF2": null,   "IP": null};
      }
   if(regex.test(line))
      {
      var NFPOS = 
         {
         "SOURCE":         1,         "PROGRAM":        2,         "PMT":            3,          "PCR":            4,         
         "TMR":            5,         "PID":            6,         "STREAMTYPE":     7,          "CHROMA":         8,        
         "BITRATE":        9,         "HSIZE":          10,        "VSIZE":          11,         "FRATE":          12,        
         "SCRAMBLE_BITS_SET": 13,     "DECRYPT_STATUS": 14,         "BITDEPTH":       15,
         "MAX":            16 //adjust accordingly
         
         };
      var input = GetDecoderSource(parseInt(line.replace(regex, "$"+NFPOS.SOURCE).toUpperCase(), 10)); 
      var pgmNo = parseInt(line.replace(regex, "$"+NFPOS.PROGRAM), 10);
      if(setting["dcmd_nf"][input] ===null){setting["dcmd_nf"][input] = [];}
      
      
      setting["dcmd_nf"][input][pgmNo] = 
         {
         "src":         parseInt(line.replace(regex, "$" + NFPOS.SOURCE), 10),
         "pgm":         parseInt(line.replace(regex, "$" + NFPOS.PROGRAM), 10),
         "pmt":         parseInt(line.replace(regex, "$" + NFPOS.PMT), 10),
         "pcr":         parseInt(line.replace(regex, "$" + NFPOS.PCR), 10),
         "tmr":         parseInt(line.replace(regex, "$" + NFPOS.TMR), 10),
         "pid":         parseInt(line.replace(regex, "$" + NFPOS.PID), 10),
         "streamtype":  parseInt(line.replace(regex, "$" + NFPOS.STREAMTYPE), 10),
         "chroma":      parseInt(line.replace(regex, "$" + NFPOS.CHROMA), 10),
         "bitrate":     parseInt(line.replace(regex, "$" + NFPOS.BITRATE), 10),
         "hsize":       parseInt(line.replace(regex, "$" + NFPOS.HSIZE), 10),
         "vsize":       parseInt(line.replace(regex, "$" + NFPOS.VSIZE), 10),
         "frate":       line.replace(regex, "$" + NFPOS.FRATE),
         "sbs":         parseInt(line.replace(regex, "$" + NFPOS.SCRAMBLE_BITS_SET), 10),
         "decryptStatus":       line.replace(regex, "$" + NFPOS.DECRYPT_STATUS),
         "bitdepth":    parseInt(line.replace(regex, "$" + NFPOS.BITDEPTH), 10)
         };
      }
   else if(naRegex.test(line))
      {//Detected No services available for an input. Ignore this line.
      }
   else
      {//regex error
      LogMyles("NF Parse Error. line: \"" + line + "\"");   
      }
   },
      
   

/************************************************** 
* Parser for OST (ONSCREENTEMPLATE) command of the decoder
**************************************************/   
CustomParse_dcmd_ost = function(command)
   {
   //TODO: Replace magic values...  use regex for parsing
   var parsedCommand = ParseCommand( command, ' ' );
   
   switch(parsedCommand[2])
      {
      case "OSDTEMPLATE":
         if(parsedCommand[4]=="OFF")
            {
            setting["dcmd_ost_active"]= false;
            setting["dcmd_ost_style"] = "OFF";
            }
         else
            {
            setting["dcmd_ost_active"]= true;
            }
         setting["dcmd_ost_style"]= parsedCommand[4];
         
         break;
      
      case "Crawl":
         setting["dcmd_ost_crawlFile"]= parsedCommand[4];
         setting["dcmd_ost_speed"]= parsedCommand[6];
         setting["dcmd_ost_direction"]= parsedCommand[8];
         setting["dcmd_ost_repeat"]= parsedCommand[10]; 
         
         break;
      
      case "Font":
         if(parsedCommand[10]=="Crawl")
            {
            setting["dcmd_ost_fontTransparency"] = (parsedCommand[9].substring(0, 2)).toUpperCase();
            setting["dcmd_ost_fontColor"] = (parsedCommand[9].substring(2)).toUpperCase();
            setting["dcmd_ost_backgroundTransparency"] = (parsedCommand[13].substring(0, 2)).toUpperCase();
            setting["dcmd_ost_backgroundColor"] = (parsedCommand[13].substring(2)).toUpperCase();
            }
         break;
      }
   },

/*******************************************************************************
 * Parser for OUTPUTASPECTRATIO command of the decoder
 ******************************************************************************/
CustomParse_dcmd_oar = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   switch(parsedCommand[3])
      {
      case "Current:":
         setting["dcmd_oar_mode"] = 'ON';
         setting["dcmd_oar_current"] = 
               parsedCommand[4].substring(0, parsedCommand[4].indexOf(","));
         setting["dcmd_oar_default"] = parsedCommand[6];
         break;
      
      case "OFF,":
         setting["dcmd_oar_mode"] = 'OFF';
         setting["dcmd_oar_current"] = 'N/A';
         setting["dcmd_oar_default"] = parsedCommand[5];
         break;
      case "AUTO,":
         setting["dcmd_oar_mode"] = 'AUTO';
         setting["dcmd_oar_current"] = 'N/A';
         setting["dcmd_oar_default"] = parsedCommand[5];
         break;   
      }
   },

/*******************************************************************************
 * Parser for DVB command of the decoder
 ******************************************************************************/
CustomParse_dcmd_dvb = function(command)
   {
   if(command.search(_UNIMPLCMDMSG)!=-1)
      { // command is not implemented. 
        // command response e.g:
        // DCMD DVB INFO-Unimplemented command
      setting["dcmd_dvb_enabled"] = false;
      }
   else
      {
      //command response e.g:
      //DCMD DVB DVBASIMODE= OFF
      var parsedCommand = ParseCommand( command, ' ' );
      setting["dcmd_dvb_enabled"] = true;
      setting["dcmd_dvb"] = parsedCommand[3];
      }
      
     
   },

/*******************************************************************************
 * Parser for SDIAUDIOMATRIX command of the decoder
 ******************************************************************************/
CustomParse_dcmd_smx = function(line)
   {
   //command response e.g:
   //DCMD SMX SDIAUDIOMATRIX CH1=1 CH2=2 CH3=3 CH4=4 CH5=5 CH6=6 CH7=7 CH8=8
   var regex = /^$/; 
   if(GetNumAudioInputs()==8)
      {
      regex = /^\s*DCMD\s+SMX\s+SDIAUDIOMATRIX\s+CH1=(\-*\d+)\s+CH2=(\-*\d+)\s+CH3=(\-*\d+)\s+CH4=(\-*\d+)\s+CH5=(\-*\d+)\s+CH6=(\-*\d+)\s+CH7=(\-*\d+)\s+CH8=(\-*\d+)\s+CH9=(\-*\d+)\s+CH10=(\-*\d+)\s+CH11=(\-*\d+)\s+CH12=(\-*\d+)\s+CH13=(\-*\d+)\s+CH14=(\-*\d+)\s+CH15=(\-*\d+)\s+CH16=(\-*\d+)\s*/i;
      }
   else if(GetNumAudioInputs()==4)
      {
      regex = /^\s*DCMD\s+SMX\s+SDIAUDIOMATRIX\s+CH1=(\-*\d+)\s+CH2=(\-*\d+)\s+CH3=(\-*\d+)\s+CH4=(\-*\d+)\s+CH5=(\-*\d+)\s+CH6=(\-*\d+)\s+CH7=(\-*\d+)\s+CH8=(\-*\d+)\s*/i;
      }
   
   var unRegex = new RegExp(""+_UNIMPLCMDMSG, "i");
   if(unRegex.test(line))
      { // command is not implemented. e.g DCMD SMX ERROR-Unimplemented command
      setting["dcmd_smx"] = null;
      }
   else if(regex.test(line))
      {
      var smxArr = [];
      for(var i=0; i<GetNumAudioInputs()*2; i++)
         {
         smxArr[i] = parseInt(line.replace(regex, "$"+(i+1)), 10);
         }
      setting["dcmd_smx"] = smxArr;
      }
   else
      {
      LogMyles("CustomParse_dcmd_smx Error"); 
      }
   },

/**************************************************
* Parser for SDIAUDIOMATRIX S0 (terse) command of the decoder
**************************************************/
CustomParse_dcmd_s0 = function(line)
   {
//   DCMD S0 STATUS idx=0 SDI=SDI SrcType=AUDIO SrcCh=15 Pid=0 Type=NA PassThruType=NA BitRate=0 SampleRate=0 ToneEn=OFF ToneMute=OFF ToneAtten=-20 dB ToneFreq=1000 Hz
//   0 0 0 15 0 NA NA 0 0 0 0 -20 1000
   if(setting["dcmd_s0"]===undefined){setting["dcmd_s0"] = {};}
   var statusRegex = /^\s*DCMD\s+S0\s+STATUS\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\w\-]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\-*\d+)\s+(\d+)\s*/i;
   var statPos = 
      {
      "dstCh": 1, "sdiType": 2, "srcType": 3, "srcCh": 4, "pid": 5,
      "streamType": 6, "bitRate": 7, "sampleRate": 8, "toneEn": 9, "toneMute": 10, "toneAtten": 11, "toneFreq": 12
      };
   if(statusRegex.test(line))
      {
      var strType = line.replace(statusRegex, "$" + statPos.streamType) == "--"? "NA": line.replace(statusRegex, "$" + statPos.streamType);
      var tmpObj = 
         {
         "sdiType":        parseInt(line.replace(statusRegex, "$" + statPos.sdiType), 10), 
         "srcType":        parseInt(line.replace(statusRegex, "$" + statPos.srcType), 10), 
         "srcCh":          parseInt(line.replace(statusRegex, "$" + statPos.srcCh), 10), 
         "pid":            parseInt(line.replace(statusRegex, "$" + statPos.pid), 10),
         "streamType":     strType, 
         "bitRate":        parseInt(line.replace(statusRegex, "$" + statPos.bitRate), 10), 
         "sampleRate":     parseInt(line.replace(statusRegex, "$" + statPos.sampleRate), 10), 
         "toneEn":         parseInt(line.replace(statusRegex, "$" + statPos.toneEn), 10), 
         "toneMute":       parseInt(line.replace(statusRegex, "$" + statPos.toneMute), 10), 
         "toneAtten":      parseInt(line.replace(statusRegex, "$" + statPos.toneAtten), 10), 
         "toneFreq":       parseInt(line.replace(statusRegex, "$" + statPos.toneFreq), 10)
         };
      
      var dstCh = parseInt(line.replace(statusRegex, "$"+ statPos.dstCh), 10);
      if(setting["dcmd_s0"].status===undefined){setting["dcmd_s0"].status = [];}
      setting["dcmd_s0"].status[dstCh] = tmpObj;
      }
   else
      {
      LogMyles("S0 status Regex failed. Line: " + line);
      }
   
   },
   
/**************************************************************************************************
* Parser for SERVICEDETAIL SVD SV (terse) command of the decoder
 *************************************************************************************************/
CustomParse_dcmd_sv = function(line)
   {
   var regex = /^\s*DCMD\s+SV\s+(ASI|RF1|RF2|IP)\s+(\d+)\s+(.+)/i;
   var POS =  { "input": 1, "svcId": 2, "jsonData": 3  };
   
   if(setting["dcmd_sv"] === undefined)
      { //init object if this is the first time the object is being invoked
      setting["dcmd_sv"] = {"ASI": [], "RF1": [], "RF2": [], "IP": []};
      } 
   if(regex.test(line))
      {
      var input, svcId;
      input = line.replace(regex, "$"+POS.input).toUpperCase();
      svcId = parseInt(line.replace(regex, "$"+POS.svcId), 10);
      setting["dcmd_sv"][input][svcId] = _yuiParseJson(line.replace(regex, "$"+POS.jsonData));
      }
   },

   
/**************************************************
* Parser for ESDIAudioMatrixHi command of the encoder (Verbose abbr)
**************************************************/   
CustomParse_ecmd_emh = function(line)
   {
   //e.g ECMD EMH ESDIAudMatrixHi= CH1=1 CH2=2 CH3=3 CH4=4 CH5=5 CH6=6 CH7=7 CH8=8
   if((setting["ecmd_emh"]===undefined) || (setting["ecmd_emh"]===null) ) {setting["ecmd_emh"] = [];}
   var regex = /^\s*ECMD\s+EMH\s+ESDIAudMatrixHi=\s+CH1=(\d+)\s+CH2=(\d+)\s+CH3=(\d+)\s+CH4=(\d+)\s+CH5=(\d+)\s+CH6=(\d+)\s+CH7=(\d+)\s+CH8=(\d+)\s*/i;
   if(regex.test(line))
      {
      for(var i=0; i<GetNumAudioInputs(); i++)
         {
         setting["ecmd_emh"][i] = parseInt( line.replace(regex, "$"+ (i+1)), 10);
         }
      }
   
   },

/**************************************************
 * Parser for ESDIAudioMatrix command of the encoder (Terse)
 **************************************************/   
CustomParse_ecmd_ex = function(line)
   {
   //line e.g "ECMD EX 1 2 3 4 5 6 7 8"
   if((setting["ecmd_ex"]===undefined) || (setting["ecmd_ex"]===null) ) {setting["ecmd_ex"] = [];}
   var regex = /^\s*ECMD\s+EX\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   if(regex.test(line))
      {
      for(var i=0; i<GetNumAudioInputs(); i++)
         {
         setting["ecmd_ex"][i] = parseInt(line.replace(regex, "$"+(i+1)), 10);
         }
      }
   else
      {
      LogMyles("Error in EX parser. Check regular expression.");
      }
   },
   
   
/**************************************************
* Parser for ESDIAudioMatrix command of the encoder (Verbose abbr)
**************************************************/
 
CustomParse_ecmd_emx = function(command)
   {
   
      
   //command response e.g:
   //ECMD EMX ESDIAudioMatrix= CH1=2 CH2=1 CH3=4 CH4=3 CH5=6 CH6=5 CH7=8 CH8=7
   //NOTE:  Channels must be grouped in pairs.
   var parsedCommand = ParseCommand( command, ' ' );

   //Ignores Even numbered channels.  They should have the same setting as the
   //previous channel. If they don't, it should be enforced once they submit
   //the video form     
   setting["ecmd_emx_1"] = parsedCommand[3].substring(4);
   setting["ecmd_emx_2"] = parsedCommand[5].substring(4);
   setting["ecmd_emx_3"] = parsedCommand[7].substring(4);
   setting["ecmd_emx_4"] = parsedCommand[9].substring(4);
      
   },
   
   
/**************************************************
* Parser for FPGAAUDIOROUTE command of the encoder
**************************************************/
CustomParse_ecmd_far = function(command)
   {
   
      
   //command response e.g:
   //ECMD FAR 1 FPGAAudioRoute1= AEN1=1 AEN2=2 AEN3=3 AEN4=4 AEN5=5 AEN6=6 AEN7=7 AEN8=8
   
   var regex = /^\s*ECMD FAR 1 FPGAAudioRoute1= AEN1=(\d+) AEN2=(\d+) AEN3=(\d+) AEN4=(\d+)\s*/i;
   if((GetProductId()==_PRODUCT.EN41.id)||(GetProductId()==_PRODUCT.EN81.id)||(GetProductId()==_PRODUCT.EN91.id))
      {//enX1 have 8 audio inputs, thus require a different regex
      regex = /^\s*ECMD FAR 1 FPGAAudioRoute1= AEN1=(\d+) AEN2=(\d+) AEN3=(\d+) AEN4=(\d+) AEN5=(\d+) AEN6=(\d+) AEN7=(\d+) AEN8=(\d+)*\s*/i;
      } 
   var cmdh = GetECMD(command);
   if(regex.test(command))
      {
      setting[cmdh + "_far_1"] = command.replace(regex, "$1");
      setting[cmdh + "_far_2"] = command.replace(regex, "$2");
      setting[cmdh + "_far_3"] = command.replace(regex, "$3");
      setting[cmdh + "_far_4"] = command.replace(regex, "$4");
      if((GetProductId()==_PRODUCT.EN41.id)||(GetProductId()==_PRODUCT.EN81.id)||(GetProductId()==_PRODUCT.EN91.id))
         {
         setting[cmdh + "_far_5"] = command.replace(regex, "$5");
         setting[cmdh + "_far_6"] = command.replace(regex, "$6");
         setting[cmdh + "_far_7"] = command.replace(regex, "$7");
         setting[cmdh + "_far_8"] = command.replace(regex, "$8");
         }
      }
   else
      {
      LogMyles("PArse error in ECMD FAR command.");
      }
   
   },
   
/*************************************************************
 * Parser for FPGAAUDIOROUTE command of the encoder for ECMD0
 ************************************************************/
CustomParse_ecmd0_far = function(command)
   {
   CustomParse_ecmd_far(command);
   },

/*************************************************************
 * Parser for FPGAAUDIOROUTE command of the encoder for ECMD1
 ************************************************************/
CustomParse_ecmd1_far = function(command)
   {
   CustomParse_ecmd_far(command);
   },

/************************************************** 
* Parser for DBF (DeBlock Filter) command of the encoder
**************************************************/   
 
CustomParse_ecmd_dbf = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd_dbf_status"] = parsedCommand[3];
   setting["ecmd_dbf_strenght"] = parsedCommand[4];
   },

   
/************************************************** 
* Parser for SNA (SERVICENAME) command of the encoder
**************************************************/   
 
CustomParse_ecmd_sna = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd_sna"] = command.substring(command.indexOf("=")+2);
     
   },

/************************************************** 
* Parser for SNA (SERVICENAME) command - hdmi2qam encoder1
**************************************************/   
 
CustomParse_ecmd0_sna = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd0_sna"] = command.substring(command.indexOf("=")+2);
     
   },

/************************************************** 
* Parser for SNA (SERVICENAME) command - hdmi2qam encoder2
**************************************************/   
 
CustomParse_ecmd1_sna = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd1_sna"] = command.substring(command.indexOf("=")+2);
     
   },
    
   
/************************************************** 
* Parser for CN (CAPTURE FILENAME) command of the encoder
**************************************************/   
 
CustomParse_ecmd_cn = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd_cn_path"] = parsedCommand[2].substring(0, parsedCommand[2].lastIndexOf("/")+1); //path
   setting["ecmd_cn_filename"] = parsedCommand[2].substring(parsedCommand[2].lastIndexOf("/")+1); //filename w/out path
        
   },
   
CustomParse_ecmd_cd = function(line)
   {
//   ECMD CD 02 AdMfg MySerial tid +1(904)9940197 48 46 This
//ECMD CD 02 Adtec 201127010 ADTEC +(904)7202003 +000.0000 +00.0000 USER.INFO______    
   var regex = /^\s*ECMD(\d+)?\s+CD\s+"(\w*)"\s+"(\w*)"\s+"(\w*)"\s+"(\w*)"\s+"([\d\+\(\)]*)"\s+"([\+\-\.\d]*)"\s+"([\+\-\.\d]*)"\s+"([\w\s\[\]\{\}'\:;<>\,\.\+\=\-\)\(\*\&\\\|\^\%\$\#@\!\`\~]*)"\s*/i;
   if (regex.test(line))
      {
      var obj = 
         {
         "format":      line.replace(regex, "$2"),
         "mfg":         line.replace(regex, "$3"),
         "serial":      line.replace(regex, "$4"),
         "id":          line.replace(regex, "$5"),
         "phone":       line.replace(regex, "$6"),
         "longitude":   line.replace(regex, "$7"),
         "latitude":    line.replace(regex, "$8"),
         "info":        line.replace(regex, "$9")
         };
      setting[GetECMD(line) + "_cd"] = obj;
      }
   else
      {
      LogMyles("Parse Error in ECMD CD parser");
      }
   },
   
CustomParse_ecmd0_cd = function(line)
   {
   CustomParse_ecmd_cd(line);
   },
   
 
/************************************************** 
* Parser for retrieving a list of PROFILES from the encoder
**************************************************/   

 
CustomParse_ecmd_profile = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   if(parsedCommand[2]=="CURRENT")
      {
      setting["ecmd_profile_current_slot"] = Trim(command.substring(21, 23));
      setting["ecmd_profile_current_name"] = Trim(command.substring(24, 64));
      }
   else
      {
   
      setting["ecmd_profile_slot"][_profileIndex] = Trim(command.substring(13, 15));//get slot
      setting["ecmd_profile_name"][_profileIndex] = Trim(command.substring(16, 56));//get name
      setting["ecmd_profile_modified"][_profileIndex] = Trim(command.substring(56));//get timestamp of last modification
      _profileIndex++;
      }
      
   },    

CustomParse_ecmd_ptx = function(command)
   {
   //command e.g
   //ECMD PTX ProcessTeletext Mode= WAVEFORM, LineEn= 0xFFFFFF
   
   var ptxRegex = /^\s*ECMD(0|1|)\s+PTX\s+PROCESSTELETEXT\s+MODE=\s+(WAVEFORM|OP47|OFF),\s+LINEEN=\s+0x((\d|A|B|C|D|E|F)+)\s*/i;
   
   if(ptxRegex.test(command))
      {
      var whichSetting1 = "ecmd_ptx_mode";
      var whichSetting2 = _PTXLINEENABLEDPREFIX;
      if (ecmd0Regex.test(command))
         {
         whichSetting1 = "ecmd0_ptx_mode";
         whichSetting2 = _PTX0LINEENABLEDPREFIX;
         }
      else if (ecmd1Regex.test(command))
         {
         whichSetting1 = "ecmd1_ptx_mode";
         whichSetting2 = _PTX1LINEENABLEDPREFIX;
         }
      setting[whichSetting1] = command.replace(ptxRegex, "$2");
      var tempLinesEnabledInHex = parseInt(command.replace(ptxRegex, "$3"), _HEXNUMBASE); //parse number in hex format
      if(!isNaN(tempLinesEnabledInHex))
         {
         
         for(var i=_MINTELTXTLINE; i<=_MAXTELTXTLINE; i++)
            {//A line is active if the digit representing it is active 
            setting[whichSetting2 + i] = (tempLinesEnabledInHex & Math.pow(2,(i-_TELTXTLINEOFFSET))) > 0;
            }
            
         //NOTE GE 10/26/2009:  Expanded loop would look something like:
         //
         //         setting["ecmd_ptx_lineenabled6"] = (tempLinesEnabledInHex & Math.pow(2,0)) > 0;
         //         setting["ecmd_ptx_lineenabled7"] = (tempLinesEnabledInHex & Math.pow(2,1)) > 0;
         //         setting["ecmd_ptx_lineenabled8"] = (tempLinesEnabledInHex & Math.pow(2,2)) > 0;
         //          .....
         //          .....
         //         setting["ecmd_ptx_lineenabled22"] = (tempLinesEnabledInHex & Math.pow(2,16)) > 0;
         
         } 
      else
         { //highly unlikely condition
         LogMyles("ECMD PTX HEX parse error.");  
         }
      }
   else
      {//highly unlikely condition
      LogMyles("ECMD PTX Regex error.");
      }
   },
   

/***************************************************************************************************
* Redirected parser for PROCESSTELETEXT API command of the encoder
***************************************************************************************************/ 

CustomParse_ecmd0_ptx = function(command)
   {
   CustomParse_ecmd_ptx(command);
   },
   

/***************************************************************************************************
* Redirected parser for PROCESSTELETEXT API command of the encoder
***************************************************************************************************/
CustomParse_ecmd1_ptx = function(command)
   {
   CustomParse_ecmd_ptx(command);
   },
         
/************************************************** 
* Parser for SPR (SERVICEPROVIDER) command of the encoder
**************************************************/   

 
CustomParse_ecmd_spr = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd_spr"] = command.substring(command.indexOf("=")+2); 
   },
       
/************************************************** 
* Parser for SPR (SERVICEPROVIDER) command - hdmi2qam encoder 1
**************************************************/   

 
CustomParse_ecmd0_spr = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd0_spr"] = command.substring(command.indexOf("=")+2); 
   },   
   
/************************************************** 
* Parser for SPR (SERVICEPROVIDER) command - hdmi2qam encoder 2
**************************************************/   

 
CustomParse_ecmd1_spr = function(command)
   {
   //get everything after the third word.  Spaces are valid in the response
   setting["ecmd1_spr"] = command.substring(command.indexOf("=")+2); 
   },   
    
   
/************************************************** 
* Parser for AMO command - hdmi2qam encoder 1
**************************************************/   

 
CustomParse_ecmd0_amo = function(command)
   {
   //third argument is 0 or 1.  e.g setting["ecmd_amo_1_mode"]
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd0_amo_" + parsedCommand[2] + "_mode"]=parsedCommand[5];
   setting["ecmd0_amo_" + parsedCommand[2] + "_type"]=parsedCommand[7];
   setting["ecmd0_amo_" + parsedCommand[2] + "_rate"]=parsedCommand[9];
   },      
   
/************************************************** 
* Parser for AMO command - hdmi2qam encoder 2
**************************************************/   
CustomParse_ecmd1_amo = function(command)
   {
   //third argument is 0 or 1.  e.g setting["ecmd_amo_1_mode"]
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd1_amo_" + parsedCommand[2] + "_mode"]=parsedCommand[5];
   setting["ecmd1_amo_" + parsedCommand[2] + "_type"]=parsedCommand[7];
   setting["ecmd1_amo_" + parsedCommand[2] + "_rate"]=parsedCommand[9];
   },

   
CustomParse_ecmd0_av = function(line)
   {
   CustomParse_ecmd_av_aux(line);
   },
CustomParse_ecmd1_av = function(line)
   {
   CustomParse_ecmd_av_aux(line);
   },

CustomParse_ecmd_av_aux = function(line)
   {
   var regex = /^\s*ECMD(\d)\s+AV\s+(\d)\s+(\-*\d+)\s*/i;
   if(regex.test(line))
      {
      var encIdx = parseInt(line.replace(regex, "$1"), 10);
      var audioPair = parseInt(line.replace(regex, "$2"), 10);
      var levVal = parseInt(line.replace(regex, "$3"), 10);
      if(setting["ecmd" + encIdx + "_av"]===undefined){setting["ecmd" + encIdx + "_av"]=[];} //error prevention
      setting["ecmd" + encIdx + "_av"][audioPair] = levVal;
      }
   else
      {
      LogMyles("Parse Error in AV response. Line: \"" + line + "\"");
      }
   },
   
CustomParse_ecmd_as_aux = function(line)
   {
   var regex = /^\s*ECMD(\d)\s+AS\s+(\d)\s+(\-*\d+)\s*/i;
   if(regex.test(line))
      {
      var encIdx = parseInt(line.replace(regex, "$1"), 10);
      var audioPair = parseInt(line.replace(regex, "$2"), 10);
      var syncVal = parseInt(line.replace(regex, "$3"), 10);
      if(setting["ecmd" + encIdx + "_as"]===undefined){setting["ecmd" + encIdx + "_as"]=[];} //error prevention
      setting["ecmd" + encIdx + "_as"][audioPair] = syncVal;
      }
   else
      {
      LogMyles("Parse Error in AS response. Line: \"" + line + "\"");
      }
   },
   
/************************************************** 
* Parser for AS command - QAM Encoder 0
**************************************************/   
CustomParse_ecmd0_as = function(line)
   {
   CustomParse_ecmd_as_aux(line);
   },
   
/************************************************** 
* Parser for AS command - QAM Encoder 1
**************************************************/   
CustomParse_ecmd1_as = function(line)
   {
   CustomParse_ecmd_as_aux(line);
   },
   

/*******************************************************************************
 * Parser for TR (TRANSPORT) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_tr = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd_tr_encodeStatus"] = GetEncodeStatus(parsedCommand[2]); //get status
   setting["ecmd_tr_encodeImage"] = GetEncodeImage(parsedCommand[2]); //get LED image
   setting["ecmd_tr_encodeUptime"] = 
        parseInt(parsedCommand[3], _DEFAULT_NUM_BASE) + " days " + parsedCommand[4]+":" //get uptime
        +   parsedCommand[5]+":"+parsedCommand[6]+"."+parsedCommand[7];
   },

/*******************************************************************************
 * Parser for TR (TRANSPORT) command of the hdmi - 1st encoder
 ******************************************************************************/
CustomParse_ecmd0_tr = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd0_tr_encodeStatus"] = GetEncodeStatus(parsedCommand[2]); //get status
   setting["ecmd0_tr_encodeImage"] = GetEncodeImage(parsedCommand[2]); //get LED image
   setting["ecmd0_tr_encodeUptime"] = 
        parseInt(parsedCommand[3], 10) + " days " + parsedCommand[4]+":" //get uptime
        +   parsedCommand[5]+":"+parsedCommand[6]+"."+parsedCommand[7];
   },

/*******************************************************************************
 * Parser for TR (TRANSPORT) command of the hdmi - 2nd encoder
 ******************************************************************************/
CustomParse_ecmd1_tr = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd1_tr_encodeStatus"] = GetEncodeStatus(parsedCommand[2]); //get status
   setting["ecmd1_tr_encodeImage"] = GetEncodeImage(parsedCommand[2]); //get LED image
   setting["ecmd1_tr_encodeUptime"] = 
        parseInt(parsedCommand[3], 10) + " days " + parsedCommand[4]+":" //get uptime
        +   parsedCommand[5]+":"+parsedCommand[6]+"."+parsedCommand[7];
   },

/*******************************************************************************
 * Parser for GOP (Group Of Pictures) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_gop = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var cmdh = GetECMD(command);
   setting[cmdh + "_gop_type"] = parsedCommand[4].substring(0, parsedCommand[4].indexOf(",")); //get type
   setting[cmdh + "_gop_struct"] = parsedCommand[6].substring(0, parsedCommand[6].indexOf(","));  //get struct
   setting[cmdh + "_gop_size"] = parsedCommand[8]; //get size
   },
   
/*******************************************************************************
 * Parser for GOP (Group Of Pictures) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_gop = function(command)
   {
   CustomParse_ecmd_gop(command);
   },

/*******************************************************************************
 * Parser for GOP (Group Of Pictures) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_gop = function(command)
   {
   CustomParse_ecmd_gop(command);
   },
   
/*******************************************************************************
 * Parser for API (Audio PID) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_api = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate line into tokens
   setting[GetECMD(command) + "_api_" + parsedCommand[2]] = parsedCommand[4];
   },
   
/*******************************************************************************
 * Parser for API (Audio PID) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_api = function(command)
   {
   CustomParse_ecmd_api(command);
   },

/*******************************************************************************
 * Parser for API (Audio PID) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_api = function(command)
   {
   CustomParse_ecmd_api(command);
   },

/*******************************************************************************
 * Parser for API (Aspect Ratio) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_ara = function(line)
   {
   var regex = /^\s*ECMD(\d+)?\s+ARA\s+AspRatio=\s*(\w+)\s*/i;
   if(regex.test(line))
      {
      setting[GetECMD(line) + "_ara"] = line.replace(regex, "$2");
      }
   else
      {
      LogMyles("ECMD_ARA Parse Error. Check Regex.");
      }
   },
   
/*******************************************************************************
 * Parser for API (Aspect Ratio) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_ara = function(line)
   {
   CustomParse_ecmd_ara(line);
   },

/*******************************************************************************
 * Parser for API (Aspect Ratio) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_ara = function(line)
   {
   CustomParse_ecmd_ara(line);
   },

/*******************************************************************************
 * Parser for ALV (Audio Level) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_alv = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third position in the array refers to the index of the audio channel <0, 1>.  5th position is the desired value
   setting[GetECMD(command) + "_alv_"+parsedCommand[2]] = parsedCommand[4];
   },

/*******************************************************************************
 * Parser for ALV (Audio Level) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_alv = function(command)
   {
   CustomParse_ecmd_alv(command);
   },
   
/*******************************************************************************
 * Parser for ALV (Audio Level) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_alv = function(command)
   {
   CustomParse_ecmd_alv(command);
   },

/*******************************************************************************
 * Parser for AUS (Audio Sync) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_aus = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third position in the array refers to the index of the audio channel <0, 1>.  5th position is the desired value
   setting[GetECMD(command) + "_aus_"+parsedCommand[2]] = parsedCommand[4];
   },

/*******************************************************************************
 * Parser for AUS (Audio Sync) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_aus = function(command)
   {
   CustomParse_ecmd_aus(command);
   },

/*******************************************************************************
 * Parser for AUS (Audio Sync) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_aus = function(command)
   {
   CustomParse_ecmd_aus(command);
   },
   
/*******************************************************************************
 * Parser for MCM (Musicam Mode) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_mcm = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third position in the array refers to the index of the audio channel <0, 1>.  6th position is the desired value
   setting[GetECMD(command) + "_mcm_"+parsedCommand[2]] = parsedCommand[5];
   },

/*******************************************************************************
 * Parser for MCM (Musicam Mode) command of the encoder for ECMD0
 ******************************************************************************/
CustomParse_ecmd0_mcm = function(command)
   {
   CustomParse_ecmd_mcm(command);
   },

/*******************************************************************************
 * Parser for MCM (Musicam Mode) command of the encoder for ECMD1
 ******************************************************************************/
CustomParse_ecmd1_mcm = function(command)
   {
   CustomParse_ecmd_mcm(command);
   },

/*******************************************************************************
 * Parser for SS1 (Snapshot1) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_ss1 = function(command)
   {
      
   var parsedCommand = ParseCommand( command, ' ' );
   switch(parsedCommand[2])
      {
      case setting["ecmd_tr_encodeStatus"]://first line of the response
      case "VideoDetected=": //second line of the response
      case "AudOnly=": //third line of the response
      case "SecondaryAud=": //fourth line of the response
      case "ControlIF=": //fifth line of the response
      case "ChromaType=": //seventh line of the response (mHUB422 Only)
      case "AudioMode0": //eight line of the response (mHUB422 Only)
      case "AudioMode1": //ninth line of the response (mHUB422 Only)
      case "AudioMode2": //tenth line of the response (mHUB422 Only)
      case "AudioMode3": //eleventh line of the response (mHUB422 Only)
         break; //ignores these lines
      
      default://parses the sixth line of the response
         setting["ecmd_ss1_tc"] = parsedCommand[6]; //timecode
         var upperByte = parseInt((parsedCommand[2]).substring(0, 1), _DEFAULT_NUM_BASE);
         var lowerByte = parseInt((parsedCommand[2]).substring(1), _DEFAULT_NUM_BASE);
         
         
         /* status data
         ----------------------------------------------------------------------------------------------
         |                  UPPER BYTE                    |                 LOWER BYTE                |           
         ----------------------------------------------------------------------------------------------
         |   Bit 7   |    Bit 6     |    Bit 5    | Bit 4 |     Bit 3    |    Bit 2   | Bit 1 | Bit 0 |
         ----------------------------------------------------------------------------------------------
         | NO MODULE | INVALID LINK | NO CASSETTE |  N/A  | TAPE TROUBLE | HARD ERROR |  N/A  | LOCAL |
         ----------------------------------------------------------------------------------------------
         */
   
         if((upperByte&8)==8){   setting["ecmd_ss1_no_module"] = true;  }
         else{ setting["ecmd_ss1_no_module"] = false;  }
         if((upperByte&4)==4){   setting["ecmd_ss1_invalid_link"] = true;  }
         else{ setting["ecmd_ss1_invalid_link"] = false;  }
         if((upperByte&2)==2){   setting["ecmd_ss1_cassette_out"] = true;  }
         else{ setting["ecmd_ss1_cassette_out"] = false;  }
         if((lowerByte&8)==8){   setting["ecmd_ss1_tape_trouble"] = true;  }
         else{ setting["ecmd_ss1_tape_trouble"] = false;  }
         if((lowerByte&4)==4){   setting["ecmd_ss1_hard_error"] = true; }
         else{ setting["ecmd_ss1_hard_error"] = false; }
         if((lowerByte&1)==1){   setting["ecmd_ss1_local"] = true;   }
         else{ setting["ecmd_ss1_local"] = false;  }
         break;
               
      }
      
   },

/*******************************************************************************
 * Parser for QV1 (Quick View) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_qv1 = function(command)
   {
//   var parsedCommand = ParseCommand( command, ' ' );
   if(_qv1Flag_line1) //identify line
      {//in line 1
      if(command.match("No Video Detected")===null )
         { 
         var resolution = command.substring(9, 18);
         setting["ecmd_qv1_hSize"] = Trim(resolution.substring(0, 4));
         setting["ecmd_qv1_vSize"] = Trim(resolution.substring(5, 9));
         setting["ecmd_qv1_frameRate"] = Trim(command.substring(19, 22));
         }
      
      _qv1Flag_line1 = false; //set flag to process line two on next iteration of this function
      }
   else
      {//in line 2      
      _qv1Flag_line1 = true; //reset flag. disregard this line
      }
   },
   
/*******************************************************************************
 * Parser for Q1 (Quick View) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_q1 = function(line)
   {
   if(!setting.ecmd_q1){setting.ecmd_q1 = {"hsize": null, "vsize": null, "frate": null, "tmr": null};}
   var topRegex = /^\s*ECMD\s+Q1\s+(\d+)\s*x\s*(\d+)\s+(\d{1,2}[a-z])\s+([\d\.]+[a-z])\s*/i;
   var noVideoRegex = /No Video Detected/i;
   if(topRegex.test(line)) //identify line
      {
      setting.ecmd_q1.hsize = parseInt(line.replace(topRegex, "$1"), 10);
      setting.ecmd_q1.vsize = parseInt(line.replace(topRegex, "$2"), 10);
      setting.ecmd_q1.frate = line.replace(topRegex, "$3");
      setting.ecmd_q1.tmr = line.replace(topRegex, "$4");
      }
   else if(noVideoRegex.test(line))
      {
      setting.ecmd_q1.hsize =  setting.ecmd_q1.vsize =  setting.ecmd_q1.frate = setting.ecmd_q1.tmr = null;
      }
   },


/*******************************************************************************
 * Parser for VDE (Video Detected) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_vde = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   if(parsedCommand[3]=="YES") { setting["ecmd_vde"] = true;  }  
   else { setting["ecmd_vde"] = false;  }
   },

/*******************************************************************************
 * Parser for AIN (Audio Input) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_ain = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["ecmd_ain_1"]
   setting[GetECMD(command) + "_ain_" + parsedCommand[2]]=parsedCommand[4];
   },

CustomParse_ecmd0_ain = function(command)
   {
   CustomParse_ecmd_ain_aux(command);
   },

CustomParse_ecmd1_ain = function(command)
   {
   CustomParse_ecmd_ain_aux(command);
   },

CustomParse_ecmd_ain_aux = function(command)
   {
   //ECMD0 AIN AInput12= ANALOG
   //ECMD1 AIN AInput12= ANALOG
   var regex = /^\s*ECMD(\d*) AIN AInput12= (.+)/i;
   
   if(regex.test(command))
      {
      setting[GetECMD(command) + "_ain"] =  command.replace(regex, "$2");
      }
   else
      {
      CustomParse_ecmd_ain(command);
      }
   },
   
CustomParse_ecmd_dp = function(line)
   {
   //response e.g:  
   var regex = /^\s*ECMD(\d+)?\s+DP\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   var key = GetECMD(line) + "_dp";
   if(regex.test(line))
      {
      if(setting[key]===undefined){setting[key]=[];}
      var obj = 
         {
         "codingMode":           parseInt(line.replace(regex, "$3"), 10),
         "bitstreamMode":        parseInt(line.replace(regex, "$4"), 10),
         "dialogNormalization":  parseInt(line.replace(regex, "$5"), 10),
         "productionInfo":       parseInt(line.replace(regex, "$6"), 10),
         "mixingLevel":          parseInt(line.replace(regex, "$7"), 10),
         "roomType":             parseInt(line.replace(regex, "$8"), 10),
         "copyright":            parseInt(line.replace(regex, "$9"), 10),
         "original":             parseInt(line.replace(regex, "$10"), 10),
         "lineModeCompression":  parseInt(line.replace(regex, "$11"), 10),
         "rfModeCompression":    parseInt(line.replace(regex, "$12"), 10),
         "rfOverModulation":     parseInt(line.replace(regex, "$13"), 10),
         "fullRangeLPF":         parseInt(line.replace(regex, "$14"), 10),
         "fullRangeDCFilter":    parseInt(line.replace(regex, "$15"), 10)
         };
      setting[key][parseInt(line.replace(regex, "$2"), 10)] = obj;
      }
   else
      {

      LogMyles("Parse Error in ECMD DP Custom Parser.  Response: \"" + line + "\"");
      }
   },
   
   
/*******************************************************************************
 * Parser for Dolby Params (deprecated)
 ******************************************************************************/
CustomParse_ecmd_dpa = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   var cmdh = GetECMD(command);
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_codingMode"]=parsedCommand[4];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_bitstreamMode"]=parsedCommand[5];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_dialogNormalization"]=parsedCommand[6];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_productionInfo"]=parsedCommand[7];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_mixingLevel"]=parsedCommand[8];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_roomType"]=parsedCommand[9];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_copyright"]=parsedCommand[10];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_original"]=parsedCommand[11];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_lineModeCompression"]=parsedCommand[12];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_rfModeCompression"]=parsedCommand[13];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_rfOverModulation"]=parsedCommand[14];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_fullRangeLPF"]=parsedCommand[15];
   setting[cmdh + "_dpa_" + parsedCommand[2] + "_fullRangeDCFilter"]=parsedCommand[16];   
   },
   
CustomParse_ecmd0_dp = function(line)
   {
   CustomParse_ecmd_dp(line);
   },
CustomParse_ecmd1_dp = function(line)
   {
   CustomParse_ecmd_dp(line);
   },
   
/*******************************************************************************
 * Parser for AIF (Feedback Path) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_aif = function(command)
   {  
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["ecmd_aif_1"]
   setting["ecmd_aif_" + parsedCommand[2]]=parsedCommand[4];
   },

/*******************************************************************************
 * Parser for LDE (Language Descriptor) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_lde = function(command)
   {  
   var parsedCommand = ParseCommand( command, ' ' );
   //third argument is 0 or 1.  e.g setting["ecmd_lde_1"]
   setting["ecmd_lde_" + parsedCommand[2].toLowerCase()]=parsedCommand[4];
   },

/*******************************************************************************
 * Parser for AMO (Audio Mode) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_amo = function(command)
   {
   //third argument is 0 or 1.  e.g setting["ecmd_amo_1_mode"]
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd_amo_" + parsedCommand[2] + "_mode"]=parsedCommand[5];
   setting["ecmd_amo_" + parsedCommand[2] + "_type"]=parsedCommand[7];
   setting["ecmd_amo_" + parsedCommand[2] + "_rate"]=parsedCommand[9]; 
   },
   
/*******************************************************************************
 * Parser for A9 (Audio Mode) command of the encoder (Terse)
 ******************************************************************************/
CustomParse_ecmd_a9 = function(line)
   {
   //response e.g: ecmd a9 0 1 3 2308000
   var regex = /^\s*ECMD\s+A9\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   if(setting["ecmd_a9"] === undefined){setting["ecmd_a9"] = [];}
   if(regex.test(line))
      {
      setting["ecmd_a9"][parseInt(line.replace(regex, "$1"), 10)] = 
         {
         "mode": parseInt(line.replace(regex, "$2"), 10),
         "type": parseInt(line.replace(regex, "$3"), 10),
         "rate": parseInt(line.replace(regex, "$4"), 10)
         };
      }
   else
      {
      LogMyles("Parse Error in ECMD A9. Line: \"" + line + "\"");
      }
   },
   
   
/*******************************************************************************
 * Parser for Multicast MMO
 ******************************************************************************/
CustomParse_ecmd_mmo = function(command)
   {
   //command e.g:
   //ECMD MMO 0 MULTICASTMODE = OFF
   
   var regex = /\s*ECMD\s+MMO\s+(\d)\s+MULTICASTMODE\s+=\s+(\w+)\s*/i;
   if(regex.test(command))
      {
      var mmoIdx = command.replace(regex, "$1");
      setting["ecmd_mmo_" + mmoIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MMO Parser error.  Regular expression did not match response");
      }
   },

/*******************************************************************************
 * Parser for Multicast Send IPA
 ******************************************************************************/
CustomParse_ecmd_msi = function(command)
   {
   //command e.g:
   //ECMD MSI 0 MULTICASTSIPA = 226.0.1.58
   var regex = /\s*ECMD\s+MSI\s+(\d)\s+MULTICASTSIPA\s+=\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/i;
   if(regex.test(command))
      {
      var msiIdx = command.replace(regex, "$1");
      setting["ecmd_msi_" + msiIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MSI Parser error.  Regular expression did not match response");
      }
      
   },

/*******************************************************************************
 * Parser for Multicast Send PORT
 ******************************************************************************/
CustomParse_ecmd_msp = function(command)
   {
   //command e.g:
   //ECMD MSP 0 MULTICASTSP = 2000
   var regex = /\s*ECMD\s+MSP\s+(\d)\s+MULTICASTSP\s+=\s+(\d{1,5})\s*/i;
   if(regex.test(command))
      {
      var mspIdx = command.replace(regex, "$1");
      setting["ecmd_msp_" + mspIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MSP Parser error.  Regular expression did not match response");
      }
   
   },

/*******************************************************************************
 * Parser for RTP
 ******************************************************************************/
CustomParse_ecmd_rtp = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd_rtp_" + parsedCommand[2]]=parsedCommand[4];
   },

/*******************************************************************************
 * Parser for TOS
 ******************************************************************************/
CustomParse_ecmd_tos = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd_tos_"+ parsedCommand[2]]=parsedCommand[4];
   },

CustomParse_ecmd0_tos = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd0_tos_"+ parsedCommand[2]]=parsedCommand[4];
   },
/*******************************************************************************
 * Parser for MCN
 ******************************************************************************/
CustomParse_ecmd_mcn = function(command)
   {
   var parsedCommand = ParseCommand(command, ' ');
   setting["ecmd_mcn_" + parsedCommand[2]] = parsedCommand[5];
   },

/*******************************************************************************
 * Parser for MCN
 ******************************************************************************/
CustomParse_ecmd0_mcn = function(command)
   {
   var parsedCommand = ParseCommand(command, ' ');
   setting["ecmd0_mcn_" + parsedCommand[2]] = parsedCommand[5];
   },
   
/*******************************************************************************
 * Parser for TTL
 ******************************************************************************/
CustomParse_ecmd_ttl = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd_ttl_"+ parsedCommand[2]]=parsedCommand[4];
   },

CustomParse_ecmd0_m0 = function(line)
   {
       
   //command e.g:
   //ECMD0 M0 0 1
//   ECMD0 M0 1 2
//   ECMD0 M0 2 0
//   ECMD0 M0 3 0
   var regex = /\s*ECMD0\s+M0\s+(\d)\s+(\d+)\s*/i;
   if(regex.test(line))
      {
      var idx = line.replace(regex, "$1");
      if(setting["ecmd0_m0"]===undefined){setting["ecmd0_m0"] = [];} //init global object on first-time use
      setting["ecmd0_m0"][idx] = line.replace(regex, "$2");
      }
   else
      {
      LogMyles("M0 Parser error.  Regular expression did not match response. Line:" + line);
      }
   
   },
   
/*******************************************************************************
 * Parser for Multicast MMO ~ H2Q
 ******************************************************************************/
CustomParse_ecmd0_mmo = function(command)
   {
       
   //command e.g:
   //ECMD MMO 0 MULTICASTMODE = OFF
//   ECMD0 MMO MULTICASTMODE = SEND
   var regex = /\s*ECMD0\s+MMO\s+(\d)\s+MULTICASTMODE\s+=\s+(\w+)\s*/i;
   if(regex.test(command))
      {
      var mmoIdx = command.replace(regex, "$1");
      setting["ecmd0_mmo_" + mmoIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MMO Parser error.  Regular expression did not match response. Line:" + command);
      }
   
   },

/*******************************************************************************
 * Parser for Multicast IPA MSI ~ H2Q
 ******************************************************************************/
CustomParse_ecmd0_msi = function(command)
   {
   //command e.g:
   //ECMD MSI 0 MULTICASTSIPA = 226.0.1.58
   var regex = /\s*ECMD0\s+MSI\s+(\d)\s+MULTICASTSIPA\s+=\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/i;
   if(regex.test(command))
      {
      var msiIdx = command.replace(regex, "$1");
      setting["ecmd0_msi_" + msiIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MSI Parser error.  Regular expression did not match response");
      }
      
   },

/*******************************************************************************
 * Parser for Multicast IPA MSP ~ H2Q
 ******************************************************************************/
CustomParse_ecmd0_msp = function(command)
   {
   //command e.g:
   //ECMD MSP 0 MULTICASTSP = 2000
   var regex = /\s*ECMD0\s+MSP\s+(\d)\s+MULTICASTSP\s+=\s+(\d{1,5})\s*/i;
   if(regex.test(command))
      {
      var mspIdx = command.replace(regex, "$1");
      setting["ecmd0_msp_" + mspIdx] = command.replace(regex, "$2");
      }
   else
      {
      LogMyles("MSP Parser error.  Regular expression did not match response");
      }
   
   },

/*******************************************************************************
 * Parser for Multicast RTP ~ H2Q
 ******************************************************************************/
CustomParse_ecmd0_rtp = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd0_rtp_" + parsedCommand[2]]=parsedCommand[4];
   },

/*******************************************************************************
 * Parser for Multicast TTL ~ H2Q
 ******************************************************************************/
CustomParse_ecmd0_ttl = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' );
   setting["ecmd0_ttl_"+ parsedCommand[2]]=parsedCommand[4];
   },

/*******************************************************************************
 * Parser for TX (Teletext Descriptor) command of the encoder
 ******************************************************************************/
CustomParse_ecmd_tx = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   setting["ecmd_tx_"+parsedCommand[2]+"_type"] = parsedCommand[3];
   setting["ecmd_tx_"+parsedCommand[2]+"_mag_num"] = parsedCommand[4];
   setting["ecmd_tx_"+parsedCommand[2]+"_page_num"] = parsedCommand[5];
      
   },
   
 
CustomParse_ecmd_vbh = function(command)
   {
   var VBH_CC_LINE_NUMBER = 21, VBH_TT_LINE_NUMBER_MIN = 6, VBH_TT_LINE_NUMBER_MAX = 22;
//Response e.g:
//    
//   ECMD VH ---VBI history---
//   ECMD VH LnNum= 21 FID= 1 Len=   2 Cnt= 27784 
//   ECMD VH   Data=  00 a5
//   ECMD VH LnNum= 10 FID= 1 Len= 193 Cnt=     1 DID/SDID= 0x0300 
//   ECMD VH   Data=  00 1f 01 07 ff 7c ff c0 ff f0 c0 f8 ff 00 ff 00 00 ff 00 03 00 3f f8 e0
//   ECMD VH          80 ff 1f 80 f0 c0 ff ff fe 07 e0 7e 00 ff 7c 0f 3f 03 ff 3f 07 e0 ff f8
//   ECMD VH          00 ff 0f 3f ff 00 c1 07 00 00 ff 00 7f ff 3f ff ff fe 07 ff fe ff 1f ff
//   ECMD VH          ff 00 00 f0 01 00 1f 7f f8 00 7f f0 3f 03 ff 01 ff 1f 81 ff e0 00 00 00
//   ECMD VH LnNum= 19 FID= 1 Len=  15 Cnt=     1 DID/SDID= 0xC0FF 
//   ECMD VH   Data=  01 07 00 00 f8 1f ff f0 00 fc f0 3f 00 00 00
   var vbhHeaderRegex = /^\s*ECMD(\d+)\s+VBH\s+---VBI\s+HISTORY---\s*/i;
   var vbhDataRegex = /^\s*ECMD(\d+)\s+VBH\s+(Data=)*\s*.+/i;
   var vbhLineRegex = /^\s*ECMD(\d+)\s+VBH\s+LnNum=\s+(\d{1,2})\s+FID=\s+(\d+)\s+Len=\s+(\d+)\s+Cnt=\s+(\d+)(\s+DID\/SDID=\s+0x((\d|A|B|C|D|E|F)+))*\s*/i;
   var sdidRegex = /DID\/SDID=/i;
   var cmd = GetECMD(command);
   if(setting[cmd + "_vbh"]===undefined || setting[cmd + "_vbh"]===null)
      {
      setting[cmd + "_vbh"] = [];
      }
   if(vbhLineRegex.test(command))
      {
      var lineNumber = command.replace(vbhLineRegex, "$2");
      var count = command.replace(vbhLineRegex, "$5");
      try 
         {
         count = parseInt(count, 10);
         }
      catch (numErr) {}
      var sdid = sdidRegex.test(command) ? command.replace(vbhLineRegex, "$7") : _NA;
      var myObj = 
         {
         "line": lineNumber,
         "fid": command.replace(vbhLineRegex, "$3"),
         "len": command.replace(vbhLineRegex, "$4"),
         "count": count,
         "sdid": sdid
         };
      setting[cmd + "_vbh"].push(myObj);
      if (_vbiHstLineCount[cmd + "_" + sdid] === undefined)
         {
         _vbiHstLineCount[cmd + "_" + sdid] = 0;
         }
      if ((lineNumber == VBH_CC_LINE_NUMBER) && (_vbiHstLineCount[cmd + "_" + sdid] < count))
         {
         setting[cmd + "_vbh"].cc_active = true;
         }
      else
         {
         setting[cmd + "_vbh"].cc_active = false;
         }
      if ((lineNumber >= VBH_TT_LINE_NUMBER_MIN) && (lineNumber <= VBH_TT_LINE_NUMBER_MAX) && (_vbiHstLineCount[cmd + "_" + sdid] < count))
         {
         setting[cmd + "_vbh"].tt_active = true;
         }
      else
         {
         setting[cmd + "_vbh"].tt_active = false;
         }
      _vbiHstLineCount[cmd + "_" + sdid] = count;
      }
   else if((vbhHeaderRegex.test(command))||(vbhDataRegex.test(command)))
      {
      if (setting[cmd + "_vbh"].length === 0)
         {
         setting[cmd + "_vbh"].tt_active = false;
         setting[cmd + "_vbh"].cc_active = false;
         }
      LogMyles("VBH Header or Data Line.  ignored..");
      }
   else
      {
      LogMyles("VBH Parse Error");
      }
   },

CustomParse_ecmd0_vbh = function(command)
   {
   CustomParse_ecmd_vbh(command);
   },

CustomParse_ecmd1_vbh = function(command)
   {
   CustomParse_ecmd_vbh(command);
   },

CustomParse_ecmd_vbp = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   if(Trim(parsedCommand[4])=="OFF,"){ setting["ecmd_vbp_mode"] = 0; } //off
   else{ setting["ecmd_vbp_mode"] = 1; } //euro text
   
   setting["ecmd_vbp_start_line"] = Trim(parsedCommand[6]).substring(0,Trim(parsedCommand[6]).length -1);
   setting["ecmd_vbp_num_lines"] = Trim(parsedCommand[8]); 
         
   },
   
   
CustomParse_dcmd_vm = function(line)
   {
   //response e.g: DCMD VM -40 -40 -40 -40
   var regex = /^\s*DCMD\s+VM\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s+(\-?\d+)\s*/i;
   if(regex.test(line))
      {
      if(!setting["dcmd_vm"]){setting["dcmd_vm"] = [];}
      setting["dcmd_vm"][0] = parseInt(line.replace(regex, "$1"), 10);
      setting["dcmd_vm"][1] = parseInt(line.replace(regex, "$2"), 10);
      setting["dcmd_vm"][2] = parseInt(line.replace(regex, "$3"), 10);
      setting["dcmd_vm"][3] = parseInt(line.replace(regex, "$4"), 10);
      }
   },

CustomParse_dcmd_vms = function(command)
   {
   //response e.g:
   // Temp= 34
   // Rail_3.3= 3281
   // Rail_1.8= 1810
   //Rail_1.2=1230
   // Rail0_0.9= 910
   // Rail1_0.9= 910
   
   var tempRegex = /^\s*DCMD\s+VMS\s+TEMP=\s*(\d+)\s*/i;
   if(tempRegex.test(command))
      {
      setting["dcmd_vms_tmp"] = parseInt(command.replace(tempRegex, "$1"), 10);
      }
   else
      {//for now, ignore every other line
         
      }
   },

CustomParse_ecmd_vms = function(command)
   {
   //response e.g:
   
   //ecmd vms Temp= 33
   //ecmd vms Rail_3.3= 3316
   //ecmd vms Rail_2.5= 2564
   //ecmd vms Rail_1.8= 1840
   //ecmd vms Rail0_1.2= 1240
   //ecmd vms Rail1_1.2= 1230
   //ecmd vms Rail2_1.2= 1240
   var tempRegex = /^\s*ECMD\s+VMS\s+TEMP=\s*(\d+)\s*/i;
   if(tempRegex.test(command))
      {
      setting["ecmd_vms_tmp"] = parseInt(command.replace(tempRegex, "$1"), 10);
      }
   else
      {//for now, ignore every other line
         
      }
   },

/*******************************************************************************
 * Parser for Custom CDE command
 ******************************************************************************/
CustomParse_ecmd_cde = function(command)
   {
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   switch(parsedCommand[2].toUpperCase())
      {
      case "CONFDECODE=":
         //ECMD CDE CONFDECODE= ON
         setting["ecmd_cde"] = parsedCommand[3]; //confidence decode
         break;
      
      case "AUTORES":
         //ECMD CDE AUTORES CDEAUTORES= ON
         setting["ecmd_cde_autores"] = parsedCommand[4]; //cde autores
         break;
      }
   },



/*******************************************************************************
 * Parser for FE (FEATURES) terse command of the encoder Used to obtain product
 * Key (product id) of the unit Specific product keys are obtained by using the
 * verbose version of the command (FEA)
 ******************************************************************************/
CustomParse_sysd_fe = function(line)
   {
   /*
    * response e.g
    * SYSD FE 29D4118C447F0F08 P
    * SYSD FE 20100318CF800092 T
    * SYSD FE 00 0000 TESTFEA
    * SYSD FE 00 0000 MP4-CHR-422E
    * SYSD FE 00 0000 MP4-CHR-420E
    * SYSD FE 01 0000 MP2-BASE
    * SYSD FE 01 0000 PDEN81
    * SYSD FE 01 0000 AUD-EXP
    * SYSD FE 00 0000 3D-SYNC-ENC
    */
   if(!setting["sysd_fe"])
      {//initialize object if it doesn't exist
      setting["sysd_fe"] = {"p": null, "t": null, "features":[]};
      }
   
   var keyRegex = /^\s*SYSD\s+FE\s+([\da-f]+)\s+([pt])\s*/i;
   var regex = /^\s*SYSD\s+FE\s+(\d+)\s+(\d+)\s+([\w\-]+)\s*/i;
   
   if(keyRegex.test(line))
      {
      setting["sysd_fe"][(line.replace(keyRegex, "$2")).toLowerCase()] = line.replace(keyRegex, "$1"); 
      }
   else if(regex.test(line))
      {
      var name = line.replace(regex, "$3");
      if(name!="TestFea") //exclude Test feature from the response object
         {
         setting["sysd_fe"].features.push(
            {
            "state":          parseInt(line.replace(regex, "$1"), 10), //0=Disabled, 1=Enabled
            "daysRemaining":  parseInt(line.replace(regex, "$2"), 10), //999=Never
            "name":           name.toLowerCase()
            });
         }
      }
   else
      {
      LogMyles("Error in SYSD_FE Local parser for line \"" + line + "\"");
      }
   
   },
//   {
//   //Response comes in separate lines. e.g:
//   //   sysd fe 28838E3D447F1510
//   //   sysd fe 0000000000000000
//   //   sysd fe 00 0000 TestFea
//   //   sysd fe 00 0000 Encod422
//   //   sysd fe 00 0000 EncodAVC
//   
//   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
//   if(parsedCommand.length==4) //discarding lines with more than 2 tokens 
//      {
//      if(parsedCommand[3] == "P")
//         {
//         setting["sysd_fe_permId"] = parsedCommand[2];
//         }
//      else if(parsedCommand[3] == "T")
//         {         
//         setting["sysd_fe_tempId"] = parsedCommand[2];
//         }
//      }
//   },

/*******************************************************************************
 * Parser for FEA (FEATURES) Verbose command of the encoder
 ******************************************************************************/
CustomParse_sysd_fea = function(line)
   {
   //e.g:
   /*
    * SYSD FEA TestFea= DISABLED
    * SYSD FEA HighDef= ENABLED, 1 days left
    * SYSD FEA AUD-EXP= ENABLED, 1 days left
    * SYSD FEA 3D-SYNC-ENC= DISABLED
    * SYSD FEA PdEN91= ENABLED
    * SYSD FEA 100LAT= DISABLED
    */
   var regex = /SYSD FEA ([\w\-]+)\= (\w+)\s*/i, 
   //          /^\s*(\w+)\s+FEA\s+(\w+)=\s+([EN|DIS]ABLED)\s*/i;
   tmpRegex =  /SYSD FEA ([\w\-]+)\= (\w+)\, (\d+) days left\s*/i; 
//   /^\s*(\w+)\s+FEA\s+(\w+)=\s+([EN|DIS]ABLED)\,\s+(\d+)\s+days\s+left\s*/i;
   var name = '', strStatus = '',  status = false, daysLeft = 0;
   
   if(tmpRegex.test(line))
      {
      name = line.replace(tmpRegex, "$1").toLowerCase();
      strStatus = line.replace(tmpRegex, "$2").toLowerCase();
      status = strStatus=="enabled";
      daysLeft = parseInt(line.replace(tmpRegex, "$3"), 10);
      }
   else if(regex.test(line))
      {
      name = line.replace(regex, "$1").toLowerCase();
      strStatus = line.replace(regex, "$2").toLowerCase();
      status = strStatus=="enabled";
      daysLeft = 999;
      }
   else
      {
      //
      LogMyles("Error in Features Parser.  Line: \"" + line + "\"");
      return;
      }
   

   if(name=="testfea"){return;} //ignore test feature

   if(!setting["features"]){setting["features"]=[];} //initialize object if it doesn't exists
   var len=setting["features"].length;
   while(len--)
      {
      if (setting["features"][len].name == name)
         {
         setting["features"].splice(len, 1);   
         }
      }
   
   setting["features"].push({
      "handler": "sysd",
      "name": name,
      "status": status
      });

   //   new generation parser
   if(!setting["fea"]){setting["fea"]={};} //init object if not defined
   if(!setting["fea"].sysd){setting["fea"].sysd={};} //init object if not defined
   setting["fea"].sysd[name] = status? 1:0; //new generation parser..
   
   var key = "sysd_fea_" + name;
   setting[key] = status;
   
   
   },



/*******************************************************************************
 * Parser for ADS command of the encoder
 ******************************************************************************/
CustomParse_ecmd_ads = function(command)
   {
   // AUDIO is ZERO Based
   //Response e.g
   //   ECMD ADS Adsp0= IDLING
   //   ECMD ADS Adsp1= IDLING
   //   ECMD ADS Adsp2= IDLING
   //   ECMD ADS Adsp3= IDLING
   //   ECMD ADS Mdsp0= IDLING
   //   ECMD ADS Mdsp1= IDLING
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   switch(parsedCommand[2])
      {
      case "Adsp0=":
         setting["ecmd_ads_adsp0"] = parsedCommand[3];
         break;
      case "Adsp1=":
         setting["ecmd_ads_adsp1"] = parsedCommand[3];
         break;
      case "Adsp2=":
         setting["ecmd_ads_adsp2"] = parsedCommand[3];
         break;
      case "Adsp3=":
         setting["ecmd_ads_adsp3"] = parsedCommand[3];
         break;
      case "Adsp4=":
         setting["ecmd_ads_adsp4"] = parsedCommand[3];
         break;
      case "Adsp5=":
         setting["ecmd_ads_adsp5"] = parsedCommand[3];
         break;
      case "Adsp6=":
         setting["ecmd_ads_adsp6"] = parsedCommand[3];
         break;
      case "Adsp7=":
         setting["ecmd_ads_adsp7"] = parsedCommand[3];
         break;
         
      case "Mdsp0=":
         setting["ecmd_ads_mdsp0"] = parsedCommand[3];
         break;
      case "Mdsp1=":
         setting["ecmd_ads_mdsp1"] = parsedCommand[3];
         break;
      case "Mdsp2=":
         setting["ecmd_ads_mdsp2"] = parsedCommand[3];
         break;
      case "Mdsp3=":
         setting["ecmd_ads_mdsp3"] = parsedCommand[3];
         break;
      default:
         LogMyles("Line \"" + command + "\" was not parsed");
         break;
          
      }
   },

/*******************************************************************************
 * Retrieve ecb parameters
 ******************************************************************************/
CustomParse_ecmd_ecb = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); // separate response into
                                       // tokens
   switch (parsedCommand[2]) 
      {
      case "EncodeColorbars=":
         setting["ecmd_ecb_enable"] = parsedCommand[3];
         break;

      case "EncodeColorbarsType=":
         setting["ecmd_ecb_type"] = parsedCommand[3];
         break;

      }
   },

/*******************************************************************************
 * Parser for SYSD GIP (Gateway ip) Verbose command
 ******************************************************************************/
CustomParse_sysd_gip = function(line)
   {
   var regex = /^\s*SYSD\s+GIP\s+GateIpAddress=\s*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/i;
   
   if(regex.test(line))
      {
      setting["sysd_gip"] = line.replace(regex, "$1");   
      }
   else
      {
      setting["sysd_gip"] = _NA;
      LogMyles("SYSD GIP Parse error.");
      }
   },

/*******************************************************************************
 * Retrieve rf stats parameters
 ******************************************************************************/
CustomParse_sysd_sts = function(command)
   {
   
   var parsedCommand = ParseCommand(command, ' '); // separate response into
                                    // tokens
   var keyVal=parsedCommand[3].split("=");
   var key = keyVal[0];
   var val = keyVal[1];
   
   switch (key) 
      {
      case "NTC7044[0]:":
         setting["sysd_sts_" + parsedCommand[2] + "_id"] = key;
         break;
      case "NTC7044[1]:":
         setting["sysd_sts_" + parsedCommand[2] + "_id"] = key;
         break;
      case "PC72xx[1]:":
         setting["sysd_sts_" + parsedCommand[2] + "_id"] = key;
         break;
      case "LOCK":
         setting["sysd_sts_" + parsedCommand[2] + "_lock"] = val;
         break;
   
      case "ES_NO":
         setting["sysd_sts_" + parsedCommand[2] + "_es_no"] = val;
         break;
      case "EB_NO":
         setting["sysd_sts_" + parsedCommand[2] + "_eb_no"] = val;
         break;
   
      case "MOD_FEC":
         setting["sysd_sts_" + parsedCommand[2] + "_mod_fec"] = val;
         break;
   
      case "LINK_MARGIN":
         setting["sysd_sts_" + parsedCommand[2] + "_link_margin"] = val;
         break;
   
      case "RECV_LEVEL":
         setting["sysd_sts_" + parsedCommand[2] + "_recv_level"] = val;
         break;
   
      case "CARRIER_FREQ_OFF":
         setting["sysd_sts_" + parsedCommand[2] + "_carrier_freq_off"] = val;
         break;
   
      case "SYM_RATE_OFF":
         setting["sysd_sts_" + parsedCommand[2] + "_symbol_rate_off"] = val;
         break;
   
      case "ROLL_OFF":
         setting["sysd_sts_" + parsedCommand[2] + "_roll_off"] = val;
         break;
   
      case "PILOT":
         setting["sysd_sts_" + parsedCommand[2] + "_pilot"] = val;
         break;
   
      case "SPEC_INV":
         setting["sysd_sts_" + parsedCommand[2] + "_special_inversion"] = val;
         break;
      case "INTRATE":
         setting["sysd_sts_" + parsedCommand[2] + "_intrate"] = val;
         break;
   
      }
   },

/*******************************************************************************
 * Retrieve rf stats parameters
 ******************************************************************************/
CustomParse_sysd_lnb = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); // separate response
   // into tokens
   switch (parsedCommand[3]) 
      {
      case "ENABLE=":
         setting["sysd_lnb_" + parsedCommand[2] + "_ENABLE"] = parsedCommand[4];
         break;
   
      case "POLARITY=":
         setting["sysd_lnb_" + parsedCommand[2] + "_POLARITY"] = parsedCommand[4];
         break;
   
      case "TONE=":
         setting["sysd_lnb_" + parsedCommand[2] + "_TONE"] = parsedCommand[4];
         break;
   
      }
   },

/*******************************************************************************
 * Parser for ADS command of the encoder1 of HDMI2QAM
 ******************************************************************************/
CustomParse_ecmd0_ads = function(command)
   {

   // Response e.g
   // ECMD0 ADS Mdsp0= IDLING
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   if(parsedCommand[3]=="Mdsp0=")
      {
      setting["ecmd0_ads_mdsp0"] = parsedCommand[4];
      }
   },

/*******************************************************************************
 * Parser for ADS command of the encoder2 of HDMI2QAM
 ******************************************************************************/
CustomParse_ecmd1_ads = function(command)
   {

   // Response e.g
   // ECMD0 ADS Mdsp0= IDLING
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   if(parsedCommand[3]=="Mdsp0=")
      {
      setting["ecmd1_ads_mdsp0"] = parsedCommand[4];
      }
   },
   
/*******************************************************************************
 * Retrieve EAS settings of the encoder 1 of HDMI2QAM
 ******************************************************************************/
CustomParse_ecmd0_eas = function(command)
   {
   //ECMD0 EAS EASMode= OFF ON
   var parsedCommand = ParseCommand( command, ' ' ); //separate response into tokens
   
   setting["ecmd0_eas_video"] = parsedCommand[3];
   setting["ecmd0_eas_audio"] = parsedCommand[4];
      
   },

/*******************************************************************************
 * Retrieve Sat Tuner Feed data parameters
 ******************************************************************************/
CustomParse_sysd_saf = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); // separate response into
                                       // tokens
   switch (parsedCommand[3])
      {
      case "ACTIVE=":
         setting["sysd_saf_" + parsedCommand[2] + "_ACTIVE"] = parsedCommand[4];
         break;
      
      case "TYPE=":
         setting["sysd_saf_" + parsedCommand[2] + "_TYPE"] = parsedCommand[4];
         break;
   
      case "DOWNLINK=":
         setting["sysd_saf_" + parsedCommand[2] + "_DOWNLINK"] = parsedCommand[4];
         break;
   
      case "LO=":
         setting["sysd_saf_" + parsedCommand[2] + "_LO"] = parsedCommand[4];
         break;
   
      case "MOD=":
         setting["sysd_saf_" + parsedCommand[2] + "_MOD"] = parsedCommand[4];
         break;
   
      case "SAT_LBAND=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_LBAND"] = parsedCommand[4];
         break;
   
      case "SAT_INTRATE=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_INTRATE"] = parsedCommand[4];
         break;
   
      case "RATE_PRI=":
         setting["sysd_saf_" + parsedCommand[2] + "_RATE_PRI"] = parsedCommand[4];
         break;
   
      case "PILOT=":
         setting["sysd_saf_" + parsedCommand[2] + "_PILOT"] = parsedCommand[4];
         break;
   
      case "ROLLOFF=":
         setting["sysd_saf_" + parsedCommand[2] + "_ROLLOFF"] = parsedCommand[4];
         break;
   
      case "SAT_SYMRATE=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_SYMRATE"] = parsedCommand[4];
         break;
   
      case "CCM=":
         setting["sysd_saf_" + parsedCommand[2] + "_CCM"] = parsedCommand[4];
         break;
      case "LO_VALUE=":
         setting["sysd_saf_" + parsedCommand[2] + "_LO_VALUE"] = parsedCommand[4];
         break;
      case "FRAMETYPE=":
         setting["sysd_saf_" + parsedCommand[2] + "_FRAMETYPE"] = parsedCommand[4];
         break;
      case "SPECINV=":
         setting["sysd_saf_" + parsedCommand[2] + "_SPECINV"] = parsedCommand[4];
         break;
      case "SAT_ACQRANGE=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_ACQRANGE"] = parsedCommand[4];
         break;
      case "SAT_RF_GAIN=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_RF_GAIN"] = parsedCommand[4];
         break;
      case "SAT_BB_GAIN=":
         setting["sysd_saf_" + parsedCommand[2] + "_SAT_BB_GAIN"] = parsedCommand[4];
         break;
      }
   },

/*******************************************************************************
 * Retrieve Sat Tuner Board Info parameters
 ******************************************************************************/
CustomParse_sysd_sup = function(command)
   {
//   var parsedCommand = ParseCommand(command, ' '); // separate response into
      //e.g SYSD SUP BOARD_ID= ADT7201 
//      e.g SYSD SUP BOARD_ID= NTC7044
//      e.g SYSD SUP ERROR-Bad Arguments
   
//      e.g SYSD SUP FIRMWARE LIST FILE_COUNT=2
//      e.g SYSD SUP FIRMWARE LIST FILE[0]=ntc6294-v1.21.ntc.tgz
//      e.g SYSD SUP FIRMWARE LIST FILE[1]=ntc6294-v1.30.ntc.tgz
   var regex = /^\s*SYSD\s+SUP\s+BOARD_(SERIAL|LICENSE|SW_VER)=\s*\"?([\w\.\/]+)"?(\s+\w+)*$/i;
   var boardIdRegex = /^\s*SYSD\s+SUP\s+BOARD_ID=\s*\"?([\w\.\/\s]+)\"?\s*/i;
   var naRegex = /^\s*SYSD\s+SUP\s+ERROR\-Bad\s+Arguments\s*$/i;
   var countRegex = /^SYSD\s+SUP\s+FIRMWARE\s+LIST\s+FILE_COUNT=(\d+)$/i;
   var fileRegex = /^SYSD\s+SUP\s+FIRMWARE\s+LIST\s+FILE\[(\d+)\]=(.*\.ntc\.tgz)$/i;
   var errorRegex = /^SYSD\s+SUP\s+FIRMWARE\s+ERROR\-(.*)$/i;
   var updateStartRegex = /^SYSD\s+SUP\s+FIRMWARE\s+START_TIME=(.*)$/i;
   var updateEndRegex = /^SYSD\s+SUP\s+FIRMWARE\s+ESTIMATED_END_TIME=(.*)$/i;
   var updateTimeRegex = /^SYSD\s+SUP\s+FIRMWARE\s+ESTIMATED_TIME_REMAINING\(s\)=(\d+)$/i;
   var updatePercentRegex = /^SYSD\s+SUP\s+FIRMWARE\s+PERCENT_COMPLETE=(\d+(\.\d+)?)$/i;
   var updateOtherRegex = /^SYSD\s+SUP\s+FIRMWARE\s+(COMPLETED|TOTAL)=(\d+)$/i;
   if (setting.sysd_sup === undefined)
      {
      setting.sysd_sup = {};
      }
   if(regex.test(command))
      {
      var line = command.replace(regex, "$1").toLowerCase();
      setting["sysd_sup_" + line] = Trim(command.replace(regex, "$2"));
      }
   else if(boardIdRegex.test(command))
      {
      setting["sysd_sup_id"] = Trim(command.replace(boardIdRegex, "$1"));
      setting["sysd_sup_id_model"] = setting["sysd_sup_id"].replace(_NEWTEC_DEMOD_REGEX, '$1');
      setting["sysd_sup_id_version"] = setting["sysd_sup_id"].replace(_NEWTEC_DEMOD_REGEX, '$2');
      }   
   else if(naRegex.test(command))
      {
      LogMyles("Demodulator is not available");
      }
   else if (countRegex.test(command))
      {
      setting.sysd_sup.count = command.replace(countRegex, "$1");
      setting.sysd_sup.file = [];
      }
   else if (fileRegex.test(command))
      {
      setting.sysd_sup.file.push(command.replace(fileRegex, "$2"));
      }
   else if (errorRegex.test(command))
      {
      setting.sysd_sup.update = false;
      }
   else if (updateStartRegex.test(command))
      {
      setting.sysd_sup.update = true;
      setting.sysd_sup.start_time = command.replace(updateStartRegex, "$1");
      }
   else if (updateEndRegex.test(command))
      {
      setting.sysd_sup.end_time = command.replace(updateEndRegex, "$1");
      }
   else if (updateTimeRegex.test(command))
      {
      setting.sysd_sup.remaining_time = command.replace(updateTimeRegex, "$1");
      }
   else if (updatePercentRegex.test(command))
      {
      setting.sysd_sup.percent_complete = parseFloat(command.replace(updatePercentRegex, "$1")).toFixed(2);
      }
   else if (updateOtherRegex.test(command))
      {
      }
   else
      {
      LogMyles("Undefined Error in SUP response.");
      }
   
   },

/*******************************************************************************
 * Retrieve Gbe Management setting
 ******************************************************************************/
CustomParse_sysd_gbm = function(command)
   {
   var parsedCommand = ParseCommand(command, ' '); // separate response into
   setting["sysd_gbm"] = parsedCommand[3];
   },

/*******************************************************************************
 * Retrieve EIT settings
 ******************************************************************************/
CustomParse_eit_sch_gul = function(line)
   {
   if(setting["eit_sch_gul"]===undefined){setting["eit_sch_gul"] = {};}
   var pollingIntervalRegex = /\s*EIT_SCH\s+GUL\s+\-p\s+(\d+)\s*/i;

   var j2cRegex = /^\s*EIT_SCH\s+GUL\s+\-c\s+[http\:\/\/]*(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d+)\/dtvGuide\/Admin\?serial=(\w+)\&method=getSourceCache\s*/i;
   var j3cRegex = /^\s*EIT_SCH\s+GUL\s+\-c\s+([ftp|http]*[\:\/\/]*\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/i;
   
   if(j2cRegex.test(line))
      {
      setting["eit_sch_gul"]["address"] =   line.replace(j2cRegex, "$1");
      setting["eit_sch_gul"]["port"] =      line.replace(j2cRegex, "$2");
      setting["eit_sch_gul"]["serial"] =    line.replace(j2cRegex, "$3");
      }
   else if(j3cRegex.test(line))
      {
      setting["eit_sch_gul"]["address"] = line.replace(j3cRegex, "$1");
      }
   else if(pollingIntervalRegex.test(line))
      {
      setting["eit_sch_gul"]["poll"] = parseInt(line.replace(pollingIntervalRegex, "$1"), 10);
      }
   else
      {
      LogMyles("EIT_SCH GUL Parse error.  Line: \"" + line + "\"");
      }
   },
   
/*******************************************************************************
 * Parses the SYSD MF API command.
 ******************************************************************************/
CustomParse_sysd_mf = function(line)
   {
   var regex = /^SYSD\s+MF\s+([A-Z\-0-9]+)\s+([A-Z0-9]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([A-Z0-9]+)\s+([0-9\-\:\@]+)\s+([0-9\-\:\@]+)/i;
   if (regex.test(line))
      {
      setting.sysd_mf = 
         {
         "productName": line.replace(regex, "$1"),
         "partName": line.replace(regex, "$2"),
         "date": line.replace(regex, "$3") + line.replace(regex, "$4") + line.replace(regex, "$5"),
         "serial": line.replace(regex, "$6"),
         "microMonitorVersion": line.replace(regex, "$7"),
         "cpldVersion": line.replace(regex, "$8")
         };
      }
   else
      {
      LogMyles("Parse error in SYSD MF API command.  Line:\"" + line + "\"");
      }
   },
   
/*******************************************************************************
 * Parses the ECMD LDE API command.
 ******************************************************************************/
CustomParse_ecmd_lde = function(command)
   {
   var regex = /^ECMD(\d+)?\s+LDE\s+(\d+\s+)?(LangAUD(\d+))=\s+(\w+)/i;
   if (regex.test(command))
      {
      setting[GetECMD(command) + "_lde_" + command.replace(regex, '$4')] = command.replace(regex, '$5');
      }
   else
      {
      LogMyles("Parse error in ECMD LDE API command.  Line:\"" + command + "\"");
      }
   },
   
/*******************************************************************************
 * Parses the ECMD LDE API command for ECMD0.
 ******************************************************************************/
CustomParse_ecmd0_lde = function(command)
   {
   CustomParse_ecmd_lde(command);
   },
   
/*******************************************************************************
 * Parses the ECMD LDE API command for ECMD1.
 ******************************************************************************/
CustomParse_ecmd1_lde = function(command)
   {
   CustomParse_ecmd_lde(command);
   },
   
/************************************************************    
 * Parses the ECMD SL API command (Terse).
 ************************************************************/ 
CustomParse_ecmd_sl = function(command)
   {
   //lines e.g "ECMD SL 0 1"
   var regex = /^\s*ECMD(\d+)?\s+SL\s+(\d+)\s+(\d+)\s*/i;
   var cmdh = GetECMD(command);
   if(regex.test(command))
      {
      setting[cmdh + "_sl"] = 
         {
         "clksrc": parseInt(command.replace(regex, "$2"), 10),
         "ecc": parseInt(command.replace(regex, "$3"), 10)
         };
      }
   else
      {
      LogMyles("Error in ECMD SL parser.");
      }
   },
   
/************************************************************
 * Parses the ECMD SL API command (Terse) for ECMD0
 ************************************************************/
CustomParse_ecmd0_sl = function(command)
   {
   CustomParse_ecmd_sl(command);
   },
   
/************************************************************    
 * Parses the ECMD SL API command (Terse) for ECMD1
 ************************************************************/ 
CustomParse_ecmd1_sl = function(command)
   {
   CustomParse_ecmd_sl(command);
   }
   ;

/*****************************************************************************
* @file
* @author Original: N/A
* @author Contributors: German Escallon
* @date Created: N/A
* @date Last Edit: $Date$ by $Author$
* Description: Entry point for MyLES.
******************************************************************************/


var
/*************************************************************************
* Entry point of the Application.  Triggers the events that launch 
* the application
*************************************************************************/
LoadMyles = function()
   { 
   if(IsMobile())
      {
      var oncssload = function(o)
         {
         LogMyles("Succesfully loaded mobile css file.");
         };
      YAHOO.util.Get.css("/css/mobile.css", {onSuccess: oncssload});
      }
   SetUiState(_UISTATE.INIT);
   var XHRSuccess = function(o)
      {
      SetUiState(_UISTATE.INSYNC);
      SetProduct(parseInt(o.responseText, _DEFAULT_NUM_BASE));
      switch(GetProductId())
         {
         case _PRODUCT.SIGNEDJE.id:
         case _PRODUCT.EDJE4111.id:
         case _PRODUCT.SOLOIST411_HW2.id:
         case _PRODUCT.DPI.id:
         case _PRODUCT.SOLOISTHDPRO.id:
            InitMyles();
            break;
         case _PRODUCT.DTA.id:
            var cb = 
               {
               success: function(o)
                  {
                  if (!ParseResponse(o))
                     {
                     LogMyles("Parse Error. System banner not properly parsed.");
                     }
                  InitMyles();
                  },
               failure: function(o)
                  {
                  LogMyles("AJAX ERROR: System banner not received.");
                  InitMyles();//Faulty state, but we continue loading the application anyways.  It is not a fatal error.
                  }
               };
            GetMyles(cb, "&q=SYSD+BANNER");
            break;
         case _PRODUCT.EN20.id:
         case _PRODUCT.YUV2QAM.id:
            if (GetProductId() == _PRODUCT.EN20.id)
               {
               var x;
               for (x = 0; x < _TAB[_TABIDX.svs].subnav.length; x++)
                  {
                  if (_TAB[_TABIDX.svs].subnav[x] == _PAGEIDX.qad)
                     {
                     _TAB[_TABIDX.svs].subnav.splice(x, 1, _PAGEIDX.ipt);
                     }
                  }
               for (x = 0; x < _TAB[_TABIDX.aud].subnav.length; x++)
                  {
                  if (_TAB[_TABIDX.aud].subnav[x] == _PAGEIDX.gau)
                     {
                     _TAB[_TABIDX.aud].subnav.splice(x, 1);
                     }
                  }
               ChangePageName(_PAGEIDX.tss, "ASI Transport");
               ChangePageName(_PAGEIDX.adc0, "Encoder 1");
               ChangePageName(_PAGEIDX.adc1, "Encoder 2");
               }
            var yuv2qamQuery = ''
               + "&q=ECMD0+TON"
               ;
            var yuv2qamCallback = 
               {
               success: function(o)
                  {
                  if (!ParseResponse(o))
                     {
                     LogMyles("PARSE Error. Table setting command not parsed.");
                     }
                  LoadBoardInfo_InitMyles();
                  },
               failure: function(o)
                  {
                  LogMyles("AJAX ERROR: Table setting not retrieved.");
                  LoadBoardInfo_InitMyles();//Faulty state, but we continue loading the application anyways.  It is not a fatal error.
                  }
               };
            GetMyles(yuv2qamCallback, yuv2qamQuery);
            break;
         case _PRODUCT.HDMI2QAM.id:
         case _PRODUCT.EN10.id:
            var hdmi2qamQuery = ''
               + "&q=ECMD0+ADS"
               + "&q=ECMD1+ADS"
               + "&q=ECMD0+TON"
               ;
            
            var hdmi2qamCallback = 
               {
               success: function(o)
                  {
                  if (!ParseResponse(o))
                     {
                     LogMyles("PARSE Error. Audio Board existance or table setting command not parsed.");
                     }
                  LoadBoardInfo_InitMyles();
                  },
               failure: function(o)
                  {
                  LogMyles("AJAX ERROR: Audio Board existance and table setting not retrieved.");
                  LoadBoardInfo_InitMyles(); //Faulty state, but we continue loading the application anyways.  It is not a fatal error.  
                  }
               };
            GetMyles(hdmi2qamCallback, hdmi2qamQuery);
            break;
         case _PRODUCT.MEDIAHUBHD.id:
         case _PRODUCT.EDJE5110.id:
            LoadBoardInfo_InitMyles();
            break;
         case _PRODUCT.MEDIAHUBHD_422.id:
            _numAudioTracks = _NUM_AUDIOTRACKS_MHHD422;
            LoadBoardInfo_InitMyles();
            break;
         case _PRODUCT.RD60.id:
            ExposeThumbnailLink();
            var rd60Query =""
               +  "&q=SYSD+SUP"
               +  "&q=DCMD+DECODESERVICE"
               +  "&q=DCMD+US"
               ;   
            
           
            var rd60Callback = 
               {
               success: function(o)
                  {
                  if(ParseResponse(o))
                     {
                     if(HasDemod())
                        {
                        _yuiEvent.onContentReady( "demodStatusPanelSection", function ()  {$("demodStatusPanelSection").style.display = ""; });//exposes demodulator status panel
                        }
                     
                     }
                  else
                     {
                     LogMyles("PARSE Error.  Sat Board Info command not parsed.");
                     }
                  LoadBoardInfo_InitMyles();
                  },

               failure: function(o)
                  {
                  LogMyles("AJAX ERROR: Sat Board Info not retrieved.");
                  LoadBoardInfo_InitMyles(); //Faulty state, but we continu8e loading the application anyways.  It is not a fatal error.  
                  }
               }; 
            GetMyles(rd60Callback, rd60Query);
            
            break;
            
         case _PRODUCT.EN40.id:
         case _PRODUCT.EN80.id:
         case _PRODUCT.EN41.id:
         case _PRODUCT.EN81.id:
         case _PRODUCT.EN91.id:
            _numAudioTracks = GetNumAudioInputs(); // dynamically set num tracks depending on product
            //Detect LBAND Modulator
            var query = '&q=SYSD+LM+PING'     ;
            
            var callback = 
               {
               success: function(o)
                  {
                  if((o.responseText).search(_LBM_PING_SUCCESS_RESPONSE)>-1)
                     {
                     _ntModSupported = true;
                     //show modulator tab
                     _yuiEvent.onContentReady(
                      "lbandModTab",
                      function () 
                         {                 
                         $("lbandModTab").style.display = ""; //exposes link to the LBandModulator Tab
                         }
                      );         
                     }
                  else{  _ntModSupported = false;   }//probably redundant, since false is the default value of this global flag
                  
                  LoadBoardInfo_InitMyles();
                  },
               failure: function(o)
                  {
                  LogMyles("AJAX Error. Could not detect LBandModulator");
                  _ntModSupported = false;
                  LoadBoardInfo_InitMyles();
                  }
               };
            GetMyles(callback, query);
            
            break;

         case _PRODUCT.DISPLAYMATE.id:
         case _PRODUCT.SOLOIST411_HW1.id:
         case _PRODUCT.ADCODE.id:
         case _PRODUCT.MEDIAHUB.id:
         case _PRODUCT.RD70.id:
         case _PRODUCT.UNKNOWN.id:
            LogMyles("ERROR: Product not supported by the UI. " +GetProductId());
            break;
            
         default:
            LogMyles("ERROR: Unrecognized product. " + GetProductId());
         }
      }; //end XHRSuccess
      
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         SetUiState(_UISTATE.ERROR);
         LogMyles("ERROR: Product identification failed");
         }
         
      };
   
   var postdataObj =  {     id:   _REQID.GETPRODUCTINDEX   };
   
   var postdataStr = _yuiStringify(postdataObj); //transform object to string 
   ConnectToReqHandler(XHRCallback, postdataStr);
      
   }, //end loadmyles() 
   

/*********************************************************************************
 * Performs Common Initialization routines for all WebUI supported ADTEC products
 **********************************************************************************/  
InitMyles = function ()
   {
   if(GetProductId() != _PRODUCT.DTA.id )
      {
      SetStatusUpdate();
      }
   RegisterPageProperties();
   DisplayStatusPanel();
   InitAudioFlags();
   SetLogPanel();
   SetDocumentTitle();
   LoadVersionNumber(); //loads version number
   LoadHelpMenus(); //loads help menus
   RenderUploadPanel(); //renders FTP applet for file uploads
   MonitorTemperature();
   LoadNavigationBar();
   LoadSubNavigationBar();
   var onNavReady = function()
      {
      var onSubnavReady = function()
         {
         InitHistoryMgr();
         };
      _yuiEvent.onContentReady(_PAGE_ID, onSubnavReady, null, false);
      };
   _yuiEvent.onContentReady(_MAIN_MENU_ID, onNavReady, null, false);
   }, 
     
/********************************************
 * Submits AJAX request to obtain HARDWARE information.
 * This is a read-only setting that will never change.
 * Therefore it is necessary to call it only once
 * for the life of the application.
 * Instantiated when loading the app.  
 *******************************************/   
LoadBoardInfo_InitMyles = function()
   {
   var query = "&q=SYSD+BI";
   if ((GetProductId() == _PRODUCT.MEDIAHUBHD.id) || IsENXX() || (GetProductId() == _PRODUCT.RD60.id) || (GetProductId() == _PRODUCT.EN20.id))
      {
      query += [
         "&q=SYSD+FE",
         "&q=SYSD+FEA"].join("");
      }
   var XHRSuccess = function(o)
      {
      if(!ParseResponse(o))
         {
         LogMyles("PARSE Error.  Board Info command not parsed.");
         }
      else
         {
         switch(GetProductId())
            {
            case _PRODUCT.MEDIAHUBHD.id:
               if(!HasFeature("MHStudio"))
                  {
                  var x = _product.tabs.length;
                  while (x--)
                     {
                     if (_product.tabs[x] == _TABIDX.std)
                        {
                        _product.tabs.splice(x, 1);
                        x = 0;
                        }
                     }
                  }
               break;
            case _PRODUCT.EN10.id:
            case _PRODUCT.EN20.id:
            case _PRODUCT.YUV2QAM.id:
               if (!HasQmod())
                  {
                  var z = _product.tabs.length;
                  while (z--)
                     {
                     if (_product.tabs[z] == _TABIDX.qam)
                        {
                        _product.tabs.splice(z, 1);
                        z = 0;
                        }
                     }
                  }
               break;
            }
         }
      InitMyles();
      };
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX ERROR: Board Info not retrieved.");
         }
      }; 
   _numPnpBoards = 0; //resets counter of pnp boards (updated when parsing the response
   GetMyles(XHRCallback, query);
   }, 
   

/********************************************
* Sumbits AJAX request to obtain HARDWARE information.
* This is a read-only setting that will never change.
* Therefore it is necessary to call it only once
* for the life of the application.
* Instantiated when loading the app.  
*******************************************/   
LoadSatBoardInfo = function()
   {
   var query =  "&q=SYSD+SUP";   
   
   var XHRSuccess = function(o)
      {
      if(!ParseResponse(o))
         {
         LogMyles("PARSE Error.  Sat Board Info command not parsed.");
         }  
      };
  
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX ERROR: Sat Board Info not retrieved.");
         }
      }; 
   GetMyles(XHRCallback, query);
  
   }, 
     
  


/*******************************************************************************************
 * This is a read-only function that returns the value of the global flag used to determine if
 * the L-BHand modulator is available for this unit and it is in a good state.
 ******************************************************************************************/
IsNtModSupported = function()
   {
   return  _ntModSupported; 
   },
   
/************************************************************
 * Sets the current product. This function needs to be called 
 * only once, at load time.  the argument is the _productIndex
 * returned by the server.
 ***********************************************************/  
SetProduct = function(prdIdx)
   {
   if(IsInt(prdIdx))
      {
      switch(prdIdx)
         {
         case 0:   _product = _PRODUCT.UNKNOWN;       break;
         case 1:   _product = _PRODUCT.DISPLAYMATE;   break;
         case 2:   _product = _PRODUCT.SIGNEDJE;      break;
         case 3:   _product = _PRODUCT.EDJE4111;      break;
         case 4:   _product = _PRODUCT.SOLOIST411_HW1;break;
         case 5:   _product = _PRODUCT.SOLOIST411_HW2;break;
         case 6:   _product = _PRODUCT.DTA;           break;
         case 7:   _product = _PRODUCT.DPI;           break;
         case 8:   _product = _PRODUCT.ADCODE;        break;
         case 9:   _product = _PRODUCT.MEDIAHUB;      break;
         case 10:  _product = _PRODUCT.MEDIAHUBHD;    break;
         case 11:  _product = _PRODUCT.SOLOISTHDPRO;  break;
         case 12:  _product = _PRODUCT.MEDIAHUBHD_422;break;
         case 13:  _product = _PRODUCT.EDJE5110;      break;
         case 14:  _product = _PRODUCT.HDMI2QAM;      break;
         case 15:  _product = _PRODUCT.RD70;          break;
         case 16:  _product = _PRODUCT.RD60;          break;
         case 17:  _product = _PRODUCT.EN40;          break;
         case 18:  _product = _PRODUCT.EN80;          break;
         case 19:  _product = _PRODUCT.YUV2QAM;       break;
         case 20:  _product = _PRODUCT.EN41;          break;
         case 21:  _product = _PRODUCT.EN81;          break;
         case 22:  _product = _PRODUCT.EN91;          break;
         case 23:  _product = _PRODUCT.EN10;          break;
         case 24:  _product = _PRODUCT.EN20;          break;
         
         default:  _product = _PRODUCT.UNKNOWN;       break;
         }
      }
   else
      {
      _product = _PRODUCT.UNKNOWN;
      }
   },
  
//TODO: Doc
RegisterPageProperties = function()
   {
   var i, j, tabIdx, pageIdx, tab;
   
   //handle exceptions
   for(i=0; i<_product.tabs.length; i++)
      {
      tabIdx = _product.tabs[i]; 
      switch(tabIdx)
         {
         case _TABIDX.mod:
            if(!IsNtModSupported())
               {//remove modulator tab completely
               _product.tabs.splice(i, 1);
               i--; //since an element of the array has been removed, the counter is decreased to avoid skipping the first element that has shifted position.
               }
            break;
            
         case _TABIDX.aud:
            for(j=0; j<GetNumAudioInputs(); j++)
               {
               _TAB[_TABIDX.aud].subnav.push(_PAGEIDX["adc" + j]);
               }
            break;

            
         case _TABIDX.inp: //verify that a demod is present before adding it
            if(HasDemod())
               {//adds demod reference
               _TAB[_TABIDX.inp].subnav.splice(_DEMODPAGEPOS, 0, _PAGEIDX.dem);
               }
            break;
         
         case _TABIDX.upg: //not all products support features page
            switch(GetProductId())
               {
               case _PRODUCT.SIGNEDJE.id:
               case _PRODUCT.DTA.id:
               case _PRODUCT.DPI.id:
               case _PRODUCT.SOLOISTHDPRO.id:
               case _PRODUCT.MEDIAHUBHD.id:
               case _PRODUCT.MEDIAHUBHD_422.id:
               case _PRODUCT.EDJE5110.id:  
               case _PRODUCT.RD70.id:
               case _PRODUCT.RD60.id:
               case _PRODUCT.EN40.id:
               case _PRODUCT.EN41.id:
               case _PRODUCT.EN80.id:
               case _PRODUCT.EN81.id:
               case _PRODUCT.EN91.id:
               case _PRODUCT.HDMI2QAM.id:
               case _PRODUCT.YUV2QAM.id:
               case _PRODUCT.EN10.id:
               case _PRODUCT.EN20.id:
                  _TAB[_TABIDX.upg].subnav.push(_PAGEIDX.fea); //add features page
                  break;
               default:
                  break;
               }
            break;
         } 
      }
   
   for(i=0; i<_product.tabs.length; i++)
      {
      tab = _TAB[_product.tabs[i]];
      for(j=0; j<tab.subnav.length; j++)
         {
         pageIdx = tab.subnav[j]; 
         switch(pageIdx)
            {
            case _PAGEIDX.adc0:            case _PAGEIDX.adc1:            case _PAGEIDX.adc2:            case _PAGEIDX.adc3:
            case _PAGEIDX.adc4:            case _PAGEIDX.adc5:            case _PAGEIDX.adc6:            case _PAGEIDX.adc7:
               _PAGE[pageIdx].render = RenderAudio;
               break;
            case _PAGEIDX.ast:
               _PAGE[pageIdx].render = RenderAsiTransport;
               break;

            case _PAGEIDX.bti:
               _PAGE[pageIdx].render = RenderBarsTonesID;
               break;
            
            case _PAGEIDX.cas:
               _PAGE[pageIdx].render = RenderCAS;
               break;
               
            case _PAGEIDX.ch0:            case _PAGEIDX.ch1:            case _PAGEIDX.ch2:            case _PAGEIDX.ch3:
            case _PAGEIDX.ch4:            case _PAGEIDX.ch5:            case _PAGEIDX.ch6:            case _PAGEIDX.ch7:
            case _PAGEIDX.ch8:            case _PAGEIDX.ch9:            case _PAGEIDX.ch10:           case _PAGEIDX.ch11:
               _PAGE[pageIdx].render = RenderChannel;
               break;
            case _PAGEIDX.cpt:
               _PAGE[pageIdx].render = RenderCaptions;
               break;
            
            case _PAGEIDX.ctl:
               _PAGE[pageIdx].render = RenderControl;
               break;
            
            case _PAGEIDX.dec:
               if(DecoderPresent())
                  {
                  _PAGE[pageIdx].render = RenderDecoder;
                  }
               break;
            
            case _PAGEIDX.dem:
               _PAGE[pageIdx].render = RenderDemod;
               break;
            
            case _PAGEIDX.dsp:
               _PAGE[pageIdx].render = RenderDisplay;
               break;
               
            case _PAGEIDX.dtv:
               _PAGE[pageIdx].render = RenderDtvConfig;
               break;
               
            case _PAGEIDX.rda:
               _PAGE[pageIdx].render = RenderRdAudio;
               break;
            
            case _PAGEIDX.eas:
               _PAGE[pageIdx].render = RenderEas;
               break;
            
            case _PAGEIDX.enc:
               _PAGE[pageIdx].render = RenderEncoder;
               break;
            
            case _PAGEIDX.fea:
               _PAGE[pageIdx].render = RenderFeatures;
               break;
            
            case _PAGEIDX.fmw:
               _PAGE[pageIdx].render = RenderFirmware;
               break;

            case _PAGEIDX.gau:
               _PAGE[pageIdx].render = RenderGlobalAudio;
               break;
            
            case _PAGEIDX.hlp:
               _PAGE[pageIdx].render = RenderHelp;
               break;
            
            case _PAGEIDX.ipp:
               _PAGE[pageIdx].render = RenderInputIp;
               break;
               
            case _PAGEIDX.inv:
               _PAGE[pageIdx].render = RenderInventory;
               break;
               
            case _PAGEIDX.ipo:
//               _PAGE[pageIdx].render = RenderOutputIp;
            _PAGE[pageIdx].render = RenderIpTransport;
               break;
               
            case _PAGEIDX.ipt:
               _PAGE[pageIdx].render = RenderIpTransport;
               break;

            case _PAGEIDX.lbm:
               _PAGE[pageIdx].render = RenderMod;
               break;
            
            case _PAGEIDX.ntp:
               _PAGE[pageIdx].render = RenderNitParams;
               break;

            case _PAGEIDX.ntw:
               _PAGE[pageIdx].render = RenderNetwork;
               break;

            case _PAGEIDX.osd:
               _PAGE[pageIdx].render = RenderOsd;
               break;

            case _PAGEIDX.pid:
               _PAGE[pageIdx].render = RenderPid;
               break;
            
            case _PAGEIDX.prf:
               _PAGE[pageIdx].render = RenderProfile;
               break;
            
            case _PAGEIDX.qad:
               _PAGE[pageIdx].render = RenderQamAudio;
            break;
            
            case _PAGEIDX.qam:
               _PAGE[pageIdx].render = RenderModulator;
               break;
               
            case _PAGEIDX.qen0:
            case _PAGEIDX.qen1:
               _PAGE[pageIdx].render = RenderQamEncoder;
               break;
               
            case _PAGEIDX.qpd:
               _PAGE[pageIdx].render = RenderQamPids;
               break;
               
            case _PAGEIDX.qvb0:
            case _PAGEIDX.qvb1:
               _PAGE[pageIdx].render = RenderQamVbi;
               break;
               
            case _PAGEIDX.rdb:
               _PAGE[pageIdx].render = RenderRdVbi;
               break;
               
            case _PAGEIDX.rdm:
               _PAGE[pageIdx].render = RenderRdSdiMatrix;
               break;
            
            case _PAGEIDX.rdo:
               _PAGE[pageIdx].render = RenderRdVideoOut;
               break;
               
            case _PAGEIDX.rdg:
               _PAGE[pageIdx].render = RenderRdGenlock;
               break;
            
            case _PAGEIDX.rds:
               _PAGE[pageIdx].render = RenderRdServices;
               break;
               
            case _PAGEIDX.sch:
               _PAGE[pageIdx].render = RenderScheduler;
               break;
            
            case _PAGEIDX.sec:
               _PAGE[pageIdx].render = RenderSecurity;
               break;
            
            case _PAGEIDX.str:
               _PAGE[pageIdx].render = RenderStreaming;
               break;
            
            case _PAGEIDX.sys:
               _PAGE[pageIdx].render = RenderSystem;
               break;
            
            case _PAGEIDX.tss:
               _PAGE[pageIdx].render = RenderServices;
               break;
            
            case _PAGEIDX.ttx:
               _PAGE[pageIdx].render = RenderTeletext;
               break;
            

            }
         }
      }

   },
   
   
 //TODO: Doc
LoadSubNavigationBar = function()
   {
   var i, j, tab, pageIdx,
   pageIdxArray = [];
   for(i=0; i<_product.tabs.length; i++)
      {
      tab = _TAB[_product.tabs[i]];
      for(j=0; j<tab.subnav.length; j++)
         {
         pageIdx = tab.subnav[j];
         switch(pageIdx)
            { //Handle special cases. Default will insert the pages as defined.
            case _PAGEIDX.dec:
               if(DecoderPresent() && (HasFeature("MHStudio") || GetProductId() == _PRODUCT.MEDIAHUBHD_422.id)) //only inserts the decoder tab if a decoder is present on the current unit.
                  {
                  pageIdxArray.push(pageIdx);
                  }
               break;
               
            case _PAGEIDX.adc:

               break;
            default: //default cases
               pageIdxArray.push(pageIdx);
               break;
            }
         }
      }
   
   var subNavMarkup = '<div id="' + _PAGE_ID + '" class="yuimenubar yuimenubarnav">';
   for(i=0; i<pageIdxArray.length; i++)
      {
      switch(pageIdxArray[i])
         {
         case _PAGEIDX.adc:
//            for(j=0; j<GetNumAudioInputs(); j++)
//               {
//               subNavMarkup += ''
//                  +  '<div id="' + _PAGE_PREFIX + _PAGE[pageIdxArray[i]].id + '_' + j + '" class="' + _SUBNAV_ITEM_CLASS + '" style="display:none;">'
//                  +     '<a class="' + _NAV_LINK_CLASS + '">' + _PAGE[pageIdxArray[i]].name + ' ' + (j+1) + '</a>'
//                  +  '</div>';
//               }
//            break;
         case _PAGEIDX.max: //temp placeholder to avoid jslint error. Impossible case that does not affect functionality.
            break;
         
         default:
            subNavMarkup += ''
               +  '<div id="' + _PAGE_PREFIX + _PAGE[pageIdxArray[i]].id + '" class="' + _SUBNAV_ITEM_CLASS + '" style="display:none;">'
               +     '<a class="' + _NAV_LINK_CLASS + '">' + _PAGE[pageIdxArray[i]].name + '</a>'
               +  '</div>';
            break;
         }
      }
   subNavMarkup+= '</div>';
   $('subNavigation').innerHTML = subNavMarkup;
   },
   
/*************************************************************************
 * Loads and renders the menu/navigation bar depending on the ADTEC product.
 **************************************************************************/      
LoadNavigationBar = function()
   {
   var i, 
   menuHTML = '<div id="' + _MAIN_MENU_ID + '" class="yuimenubar yuimenubarnav">' ;
   for(i=0; i<_product.tabs.length; i++)
      {
      menuHTML += ''
         +  '<div class="' + _NAV_ITEM_CLASS + '" id="' + _TAB_PREFIX + _TAB[_product.tabs[i]].id + '">' 
         +     '<a class="' + _NAV_LINK_CLASS + '">' + _TAB[_product.tabs[i]].name + '</a>'
         +  '</div>'
         ;
      }
   menuHTML += '</div>';
   
   $('navigation').innerHTML = menuHTML;

   
   /*
    Initialize and render the MenuBar when its elements are ready 
    to be scripted.
    */ 
   _yuiEvent.onContentReady(_MAIN_MENU_ID, OnNavBarRendered, null, false);
   
      
     
   },  //end LoadNavigationBar

//TODO:
OnNavBarRendered = function()
   {
   /*
    Instantiate a MenuBar:  The first argument is the id of the element in the page 
    representing the MenuBar; the second is an object literal of configuration properties.
   */ 
   var menuBarConfig = { hidedelay: _NAVIGATION_DELAY_TIMEOUT, lazyload: true }; 
   var oMenuBar = new YAHOO.widget.MenuBar( _MAIN_MENU_ID, menuBarConfig );
  
   oMenuBar.render();
   },

//TODO:
InitThumbnailPanel = function()
   {
   var tp = RenderThumbnailPanel();
   _yuiEvent.addListener ("displayLinkId", "click",  ShowThumbnailPanel, tp, true);   
   },
   
   
//Exposes the thumbnail link on the upper-right corner, which is hidden by default.
ExposeThumbnailLink = function()
   {
   $("displayLinkId").style.display = "";
   _yuiEvent.onContentReady("thumbnailAlignDiv", InitThumbnailPanel, null, false);
   },
   
/********************************************************************************
 * Returns true if the installed Demodulator supports RF Gain.  False otherwise.
 *********************************************************************************/   
SupportsRfGain = function()
   {
   var vrsnRegex = /(\d+\.\d*).*/;
   var vrsn = parseFloat(setting["sysd_sup_sw_ver"].replace(vrsnRegex, "$1"));
   return (vrsn >= _MIN_NT_SW_VR_FOR_RF_GAIN_SUPPORT) &&
      (GetBoardFeatureKeyList(setting["sysd_sup_license"])[0]!=="ALL") &&
      setting["sysd_sup_id_model"] == '7044' &&
      setting["sysd_sup_id_version"] == 'AB'
      ; 
   }
   ;
/*****************************************************************************
* @file
* @author Original: German Escallon
* @author Contributors: 
* @date Created: 2011/12/31
* @date Last Edit: $Date$ by $Author$
* Description: Parses data locally.  does not pollute the global namespace.
******************************************************************************/

var

GetResponsePrefix = function(line)
   {
   var prefix = null;
   var regex = /^(SYSD|DCMD|ECMD[01]*|DPID|EIT) (\w+) (.+)/i;
   if(regex.test(line))
      {
      prefix = ("" + line.replace(regex, "$1") + "_" + line.replace(regex, "$2")).toLowerCase();
      }
   return prefix;
   },
   
ParseLocally = function(response)
   {
   var result = {};
   var group = {};
   
   var responseData = (response).split("\n");
   for(var i=0; i<responseData.length; i++)
      {//for each line in the response
      var cleanLine = CleanupString(responseData[i]);
      if(cleanLine.length<=0){continue;} //skips empty lines
      var prefix = GetResponsePrefix(cleanLine);
      if(prefix===null)
         {
         LogMyles("ERROR: Prefix not determined for line " + cleanLine);
         return null;
         }
      if((result[prefix]===undefined) || (result[prefix]===null))
         {
         result[prefix] = {};
         group[prefix] = [];
         }
      group[prefix].push(cleanLine);
      }
   var arr;
   
   
   for( arr in group) 
      {
      if(true) //Needed to satisfy JSLINT rule:  "The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype.".   
         { 
         switch(arr)
            {
            case "dcmd_dc":
            case "dcmd_rv":
            case "dcmd_s6":
            case "dcmd_vi":

            case "ecmd_af": //audio sample frequency
            case "ecmd_ag":
            case "ecmd0_cc":
            case "ecmd1_cc":
            case "ecmd0_hs":
            case "ecmd1_hs":
            case "ecmd0_it":
            case "ecmd1_it":
            case "ecmd0_v2":
            case "ecmd1_v2":
               result[arr] = ParseTerse_std(group[arr][0]);
               break;
            
            case "dcmd_0s":
            case "dcmd_dit":
            case "dcmd_dg": 
            case "dcmd_dk": 
            case "dcmd_its":
            case "dcmd_decodeservice":
            case "dcmd_nf":
            case "dcmd_s0":
            case "dcmd_tc":
            case "dcmd_vc":
            case "dcmd_vh":
            
            case "ecmd_sl":

            case "ecmd0_lde":
            case "ecmd1_lde":
            case "ecmd0_tx":
            case "ecmd1_tx":
            case "ecmd0_q1":
            case "ecmd1_q1":
            case "ecmd0_p5":
            case "ecmd1_p5":
            case "ecmd0_ton":
            case "ecmd1_ton":
            
            case "sysd_bi":
            case "sysd_dt":
            case "sysd_fe":
            case "sysd_na":
            case "sysd_profile":
            case "sysd_mf":
            case "sysd_ss":
            case "sysd_systemprofile":
            case "sysd_ug":
               result[arr] = window["LocalParse_" + arr](group[arr]);
               break;
               
            default:
               LogMyles("Unrecognized API prefix \"" + arr + "\"");
               return null;
            }
         }
      }
   
   return result;
   },

   
LocalParse_dcmd_dit = function(lines)
   {
   var result = null;
   var line = lines[0]; //only one line is expected.
   
   //gets the first argument of the response and removes the "," immediately after it
   //Response e.g DCMD DIT DECODERINPUT= RF1 1 
   var regex = /^\s*DCMD\s+DIT\s+DECODERINPUT=\s+(ASI|RF[12]|IP)\s+(\-*\d+)\s*/i;
   if(regex.test(line))
      {
      result = 
         {
         "input": line.replace(regex, "$1"),
         "svcId": parseInt(line.replace(regex, "$2"), 10)
         };
      }
   else
      {
      LogMyles("DCMD DIT Parse error");
      }
   return result;
   },
/*********************************************************
 * Local Custom Parser for DIT API
 *********************************************************/
LocalParse_dcmd_0s = function(lines)
   {
   var result = null;
   var line = lines[0]; //only one line is expected.
   
   var regex = /^\s*DCMD\s+0S\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\"(.*)\"\s*/i;
   if(regex.test(line))
      {
      result = 
         {
         "mode":           parseInt(line.replace(regex, "$1"), 10),
         "output":         parseInt(line.replace(regex, "$2"), 10),
         "svc_mode":       parseInt(line.replace(regex, "$3"), 10),
         "svc_lines":      parseInt(line.replace(regex, "$4"), 10),
         "svc_blink":      parseInt(line.replace(regex, "$5"), 10),
         "svc_x_pos":      parseInt(line.replace(regex, "$6"), 10),
         "svc_y_pos":      parseInt(line.replace(regex, "$7"), 10),
         "txt_size":       parseInt(line.replace(regex, "$8"), 10),
         "str_format":     parseInt(line.replace(regex, "$9"), 10),
         "str_blink":      parseInt(line.replace(regex, "$10"), 10),
         "str_x_pos":      parseInt(line.replace(regex, "$11"), 10),
         "str_y_pos":      parseInt(line.replace(regex, "$12"), 10),
         "str_len":        parseInt(line.replace(regex, "$13"), 10),
         "string":         line.replace(regex, "$14")
         };

      }
   else
      {
      LogMyles("DCMD 0s Parse error");
      }
   return result;
   },
   
/*********************************************************
 * Local Custom Parser for DECODEGENLOCK API
 *********************************************************/
LocalParse_dcmd_dg = function(lines)
   {
   var result = {};
   var mainRegex = /^\s*DCMD\s+DG\s+(\d+)\s+(\-*\d+)\s+(\-*\d+)\s+(\d+)\s+(\d+)\s*/i ;
   var statusRegex = /^\s*DCMD\s+DG\s+STATUS\s+(\d+)\s+(\w+)\s+(\w+)\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   
   for(var i=0; i<lines.length; i++)
      {
      var line = lines[i];
      if(mainRegex.test(line))
         {
         result.mode = parseInt(line.replace(mainRegex, "$1"), 10);
         result.hadj = parseInt(line.replace(mainRegex, "$2"), 10);
         result.vadj = parseInt(line.replace(mainRegex, "$3"), 10);
         result.padj = parseInt(line.replace(mainRegex, "$4"), 10);
         result.cvbs = parseInt(line.replace(mainRegex, "$5"), 10);
         }
      else if(statusRegex.test(line))
         {
         var statusObj = 
            {
            "state":                parseInt(line.replace(statusRegex, "$1"), 10),
            "sync_sep_format":      line.replace(statusRegex, "$2"), 
            "ref_video_standard":   line.replace(statusRegex, "$3"),
            "out_video_standard":   line.replace(statusRegex, "$4"),
            "valid_cross_ref":      parseInt(line.replace(statusRegex, "$5"), 10), 
            "ref_locked":           parseInt(line.replace(statusRegex, "$6"), 10), 
            "dec_status":           parseInt(line.replace(statusRegex, "$7"), 10), 
            "lock_lost_count":      parseInt(line.replace(statusRegex, "$8"), 10),
            "ref_lost_count":       parseInt(line.replace(statusRegex, "$9"), 10), 
            "video_skip_count":     parseInt(line.replace(statusRegex, "$10"), 10),
            "video_repeat_count":   parseInt(line.replace(statusRegex, "$11"), 10)        
            };
         result.status = statusObj;
         }
      else
         {
         LogMyles("LocalParse_dcmd_dg parse error."); 
         }
      }
   return result;
   },
   
LocalParse_dcmd_dk = function(lines)
   {
   var result = null;
   var regex = /\s*DCMD\s+DK\s+(\d+)\s+(\d+)\s*/i,
   line = lines[0]; //only one line is expected in the response
   if(regex.test(line))
      {
      result = 
         {
         "mode": parseInt(line.replace(regex, "$1"), 10),
         "type": parseInt(line.replace(regex, "$2"), 10)
         };
      }
   return result;
   },
   
LocalParse_dcmd_its = function(lines)
   {
   var result = [];
// response e.g
   /*
   DCMD ITS ASI 201 "TNT East" "Adtec Digital"
   DCMD ITS ASI 202 "Toon East" "Adtec Digital"
   DCMD ITS ASI 203 "TBS East" "Adtec Digital"
   DCMD ITS ASI 204 "Tru TV East" "Adtec Digital"
   DCMD ITS ASI 205 "CNN East" "Adtec Digital"
   DCMD ITS RF1 Services Unavailable
   DCMD ITS RF2 Services Unavailable
   DCMD ITS IP Services Unavailable
    */
   var INPUT_PORT_POS = 1, PGM_ID_POS =2, PGM_NAME_POS = 3, PGM_PROV_POS = 4;
   var regex = /^\s*DCMD\s+ITS\s+(ASI|RF1|RF2|IP)\s+(\d+)\s+"(.*)"\s+"(.*)"\s*/i;
   var naRegex = /^\s*DCMD\s+ITS\s+(ASI|RF1|RF2|IP)\s+SERVICES UNAVAILABLE\s*/i;
   

   for(var i=0; i<lines.length; i++)
      {
      if(naRegex.test(lines[i]))
         {
        // Commented out to allow page load when condition exists. It is valid.
         //LogMyles("No available services for " + lines[i].replace(regex, "$"+INPUT_PORT_POS));
         }
      else if(regex.test(lines[i]))
         {
         var port = lines[i].replace(regex, "$"+INPUT_PORT_POS);
         var pgmId = lines[i].replace(regex, "$"+PGM_ID_POS);
         var pgmName = lines[i].replace(regex, "$"+PGM_NAME_POS);
         var pgmProv = lines[i].replace(regex, "$"+PGM_PROV_POS);
         
         var obj = 
            {
            "port":        port,
            "pgm_id":      pgmId,
            "pgm_name":    pgmName,
            "pgm_prov":    pgmProv
            };
         
         if((setting["dcmd_its"]===undefined) || (setting["dcmd_its"] === null)){setting["dcmd_its"] = [];} //init array if it doesn't exist
         result.push(obj); //add new object to created array
         }
      else
         {
         LogMyles("Error in DCMD ITS parser.");
         }
      }
   
   return result;
   },
   
/***********************************
 * Local parser for decode service
 ************************************/
LocalParse_dcmd_decodeservice = function(lines)
   {
// response e.g
   /*
    DCMD DECODESERVICE ASI 201 "TNT East" "Adtec Digital"
 */
   var result = null;
   var line = lines[0]; //only one line is expected.
      
   var dsRegex =  /^\s*DCMD\s+DECODESERVICE\s+(ASI|RF1|RF2|IP)\s+(\d+)\s+"(.*)"\s+"(.*)"\s*/i;
   var dsnaRegex = /^\s*DCMD\s+DECODESERVICE\s+No active services found\s*/i;
   
   
   if(dsnaRegex.test(line))
      {
      result = 
         {
         "enabled":        false,
         "port":           "--N/A--",
         "number":         "--N/A--",
         "name":           "--N/A--",
         "provider":       "--N/A--"
         };
      }
   else if (dsRegex.test(line))
      {
      result = 
         {
         "enabled":        true,
         "port":           line.replace(dsRegex, "$1"),
         "number":         line.replace(dsRegex, "$2"),
         "name":           line.replace(dsRegex, "$3"),
         "provider":       line.replace(dsRegex, "$4")
         };
      }
   else
      {
      LogMyles("DCMD DECODESERVICE LOCAL PARSE ERROR.");
      }
   return result;
   },
   
/************************************************************    
 * Parses the DCMD VBICONF (VC) API command (Terse).
 ************************************************************/
LocalParse_dcmd_vc= function(lines)
   {
   /*Lines e.g:
    *    [
   "DCMD VC CVBS CAPTIONS 21",
   "DCMD VC CVBS TELETEXT 22",
   "DCMD VC SDI AFD 11",
   "DCMD VC SDI CAPTIONS 11",
   "DCMD VC SDI TELETEXT 22",
   "DCMD VC SDI VITC 14",
   "DCMD VC SDIALT AFD 11",
   "DCMD VC SDIALT CAPTIONS 11",
   "DCMD VC SDIALT TELETEXT 22",
   "DCMD VC SDIALT VITC 0"
   ]
    */
   
   var result = {};
//   var regex = /DCMD VC CVBS AFD 255/i
//   var regex = /\s*DCMD\s+VC\s+([CVBS|SDI|SDIALT|0-2])\s+([CAPTIONS|TELETEXT|VITC|AFD|0-3])\s+(\d+)\s*/i;
   var regex = /^\s*DCMD\s+VC\s+(CVBS|SDI[ALT]*)\s+(CAPTIONS|TELETEXT|VITC|AFD)\s+(\d+)\s*/i;
   for(var i=0; i<lines.length; i++)
      {
      if(regex.test(lines[i]))
         {
         var output = (lines[i].replace(regex, "$1")).toLowerCase();
         var type = (lines[i].replace(regex, "$2")).toLowerCase();
         var lineNum = parseInt(lines[i].replace(regex, "$3"), 10);
         if(isNaN(lineNum))
            {
            LogMyles("DCMD VC Parse Error. Unknown line number");
            continue;
            }
         
         if(!isNaN(parseInt(output, 10)))
            { //Convert output from int to string
            switch(parseInt(output, 10))
               {
               case 0: output = "cvbs"; break;
               case 1: output = "sdi"; break;
               case 2: output = "sdialt"; break;
               default:
                  LogMyles("DCMD VC Parse Error. Unknown output index");
                  return null;
               }
            }
         
         if(!isNaN(parseInt(type, 10)))
            {//Convert type from int to string
            switch(parseInt(type, 10))
               {
               case 0: type = "captions"; break;
               case 1: type = "teletext"; break;
               case 2: type = "vitc"; break;
               case 3: type = "afd"; break;
               default:
                  LogMyles("DCMD VC  Parse Error. Unknown output type index");
                  return null;
               }
            }
         
         if(result[output]===undefined){result[output]={};}
         
         result[output][type]= lineNum;
         
         }
      else
         {
         LogMyles("Parse Error in line \"" + lines[i] + "\". Check Regex."); 
         }
      
      }
   return result;
   },
   
/************************************************************    
 * Parses the DCMD VH (VBIHISTORY) API command (Terse).
 ************************************************************/
LocalParse_dcmd_nf = function(lines)
   {
   /*
    *  Response e.g:
    *   "DCMD NF 1 1 101 110 23373044 110 27 1 0 1280 720 59.94p 0 0" 
    *   "DCMD NF 1 2 102 210 23358678 210 27 1 0 1280 720 59.94p 0 0" 
    *   "DCMD NF 1 3 103 310 23344312 310 27 1 0 1280 720 59.94p 0 0" 
    *   "DCMD NF 2 1 100 101 9722853 101 27 1 0 1920 1080 29.97i 0 0"
    */    
   var regex = /^\s*DCMD\s+NF\s+(\d+)\s+(\d+)\s+([0x]*[0-9a-fA-F]+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+([0x]*[0-9a-fA-F]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d|\.]+[i|p]*)\s+(\d+)\s+(\d+)\s*/i;
   var naRegex = /^\s*DCMD\s+NF\s+(\d+)[\s+No Services Available]*\s*/i;
   var NFPOS = 
      {
      "SOURCE":         1,         "PROGRAM":        2,         "PMT":            3,          "PCR":            4,         
      "TMR":            5,         "PID":            6,         "STREAMTYPE":     7,          "CHROMA":         8,        
      "BITRATE":        9,         "HSIZE":          10,        "VSIZE":          11,         "FRATE":          12,        
      "SCRAMBLE_BITS_SET": 13,     "DECRYPT_STATUS": 14,
      "MAX":            15 //adjust accordingly
      
      };
   
   var resultObj = {  "ASI": null,   "RF1": null,   "RF2": null,   "IP": null, "active": false};
   var line = '';
   for(var i=0; i<lines.length; i++)
      {
      line = lines[i];
      if(regex.test(line))
         {
         resultObj.active = true;
         var input = GetDecoderSource(parseInt(line.replace(regex, "$"+NFPOS.SOURCE).toUpperCase(), 10)); 
         var pgmNo = parseInt(line.replace(regex, "$"+NFPOS.PROGRAM), 10);
         if((resultObj[input]===undefined)||(resultObj[input] ===null)){resultObj[input] = [];}
         
         resultObj[input][pgmNo] = 
            {
            "src":         parseInt(line.replace(regex, "$" + NFPOS.SOURCE), 10),
            "pgm":         parseInt(line.replace(regex, "$" + NFPOS.PROGRAM), 10),
            "pmt":         parseInt(line.replace(regex, "$" + NFPOS.PMT), 10),
            "pcr":         parseInt(line.replace(regex, "$" + NFPOS.PCR), 10),
            "tmr":         parseInt(line.replace(regex, "$" + NFPOS.TMR), 10),
            "pid":         parseInt(line.replace(regex, "$" + NFPOS.PID), 10),
            "streamtype":  parseInt(line.replace(regex, "$" + NFPOS.STREAMTYPE), 10),
            "chroma":      parseInt(line.replace(regex, "$" + NFPOS.CHROMA), 10),
            "bitrate":     parseInt(line.replace(regex, "$" + NFPOS.BITRATE), 10),
            "hsize":       parseInt(line.replace(regex, "$" + NFPOS.HSIZE), 10),
            "vsize":       parseInt(line.replace(regex, "$" + NFPOS.VSIZE), 10),
            "frate":       line.replace(regex, "$" + NFPOS.FRATE),
            "sbs":         parseInt(line.replace(regex, "$" + NFPOS.SCRAMBLE_BITS_SET), 10),
            "decryptStatus":       line.replace(regex, "$" + NFPOS.DECRYPT_STATUS)
            };
         
         }
      else if(naRegex.test(line))
         {//Detected No services available for an input. Ignore this line.
         
         }
      else
         {//regex error
         LogMyles("NF Parse Error. line: \"" + line + "\"");   
         }   
      }
   return resultObj;
   },
   
LocalParse_dcmd_s0 = function(lines)
   {
   var result = {"status": [], "matrix": []};
   var regex = /^\s*DCMD\s+S0\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,\s+(\-?\d+)\,?\s*/i;
   var statusRegex = /^\s*DCMD\s+S0\s+STATUS\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\w\-]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\-*\d+)\s+(\d+)\s*/i;
   var line = -1;
   for(var j=0; j<lines.length; j++)
      {
      line = lines[j];
      if(regex.test(line))
         {
         for(var i=0; i<_AUDIO_NUM_SDI_CHANNELS; i++)
            {
            result.matrix[i] = parseInt(line.replace(regex, "$"+(i+1)), 10);
            }
         }
      else if(statusRegex.test(line))
         {
         var statPos = 
            {
            "dstCh": 1, "sdiType": 2, "srcType": 3, "srcCh": 4, "pid": 5,
            "streamType": 6, "bitRate": 7, "sampleRate": 8, "toneEn": 9, "toneMute": 10, "toneAtten": 11, "toneFreq": 12
            };
         
         var strType = line.replace(statusRegex, "$" + statPos.streamType) == "--"? "NA": line.replace(statusRegex, "$" + statPos.streamType);
         var tmpObj = 
            {
            "sdiType":        parseInt(line.replace(statusRegex, "$" + statPos.sdiType), 10), 
            "srcType":        parseInt(line.replace(statusRegex, "$" + statPos.srcType), 10), 
            "srcCh":          parseInt(line.replace(statusRegex, "$" + statPos.srcCh), 10), 
            "pid":            parseInt(line.replace(statusRegex, "$" + statPos.pid), 10),
            "streamType":     strType, 
            "bitRate":        parseInt(line.replace(statusRegex, "$" + statPos.bitRate), 10), 
            "sampleRate":     parseInt(line.replace(statusRegex, "$" + statPos.sampleRate), 10), 
            "toneEn":         parseInt(line.replace(statusRegex, "$" + statPos.toneEn), 10), 
            "toneMute":       parseInt(line.replace(statusRegex, "$" + statPos.toneMute), 10), 
            "toneAtten":      parseInt(line.replace(statusRegex, "$" + statPos.toneAtten), 10), 
            "toneFreq":       parseInt(line.replace(statusRegex, "$" + statPos.toneFreq), 10)
            };
         var dstCh = parseInt(line.replace(statusRegex, "$"+ statPos.dstCh), 10);
         result.status[dstCh] = tmpObj;
         }
      else
         {
         LogMyles("Parse error in LocalParse_dcmd_s0. Line: \"" + line+"\"");
         }
      }
   return result;
   },

/************************************************************    
 * Parses the DCMD TC (VBIHISTORY) API command (Terse).
 ************************************************************/
LocalParse_dcmd_tc = function(lines)
   {
   var result = {};
   var line = lines[0]; //only 1 line is expected

   //e.g dcmd TC 0 0 0
   var regex = /^\s*DCMD\s+TC\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
//   Source, SdiOutput, SdiAltOutput
   if(regex.test(line))
      {
      result = 
         {
         "source":            parseInt(line.replace(regex, "$1"), 10),
         "sdioutput":         parseInt(line.replace(regex, "$2"), 10),
         "sdialtoutput":      parseInt(line.replace(regex, "$3"), 10)
         };   
      }
   else
      {
      LogMyles("Parse error in LocalParse_dcmd_tc. Line: \"" + line+"\"");
      }
   
   return result;
   },
/************************************************************    
 * Parses the DCMD VH (VBIHISTORY) API command (Terse).
 ************************************************************/
LocalParse_dcmd_vh = function(lines)
   {
   
   /*
   input e.g: 
      DCMD VBH CVBS DETAIL --Captions----
      DCMD VBH CVBS DETAIL Enable= TRUE
      DCMD VBH CVBS DETAIL Insert Line= 21
      DCMD VBH CVBS DETAIL Present= FALSE
      DCMD VBH CVBS DETAIL Count= 0
      DCMD VBH CVBS DETAIL 608 Len= 0
      DCMD VBH CVBS DETAIL 708 Len= 0
      DCMD VBH CVBS DETAIL DID/SDID= 0x0000
      DCMD VBH CVBS DETAIL 3:2 Pulldown= FALSE
      DCMD VBH CVBS DETAIL Seq Cnt= 0
      DCMD VBH CVBS DETAIL Cdp Pkt Size= 0
      DCMD VBH CVBS DETAIL --Teletext----
      DCMD VBH CVBS DETAIL Enable= TRUE
      DCMD VBH CVBS DETAIL Present= FALSE
      DCMD VBH CVBS DETAIL PID= 0x0000
      DCMD VBH CVBS DETAIL Active Lines= 0x0000
      DCMD VBH SDI DETAIL --Captions----
      DCMD VBH SDI DETAIL Enable= TRUE
      DCMD VBH SDI DETAIL Insert Line= 11
      DCMD VBH SDI DETAIL Present= FALSE
      DCMD VBH SDI DETAIL Count= 0
      DCMD VBH SDI DETAIL 608 Len= 0
      DCMD VBH SDI DETAIL 708 Len= 0
      DCMD VBH SDI DETAIL DID/SDID= 0x0000
      DCMD VBH SDI DETAIL 3:2 Pulldown= FALSE
      DCMD VBH SDI DETAIL Seq Cnt= 0
      DCMD VBH SDI DETAIL Cdp Pkt Size= 0
      DCMD VBH SDI DETAIL --Afd----
      DCMD VBH SDI DETAIL Enable= TRUE
      DCMD VBH SDI DETAIL Insert Line= 9
      DCMD VBH SDI DETAIL Present= FALSE
      DCMD VBH SDI DETAIL DID/SDID= 0x0000
      DCMD VBH SDI DETAIL Active Fmt Flg= 0
      DCMD VBH SDI DETAIL Afd Code= 0x00
      DCMD VBH SDI DETAIL AR Flag= 0
      DCMD VBH SDI DETAIL Bar Data Top= 0
      DCMD VBH SDI DETAIL Bar Data Btm= 0
      DCMD VBH SDI DETAIL Bar Data Left= 0
      DCMD VBH SDI DETAIL Bar Data Right= 0
      DCMD VBH SDI DETAIL --VITC----
      DCMD VBH SDI DETAIL Enable= TRUE
      DCMD VBH SDI DETAIL Present= FALSE
      DCMD VBH SDI DETAIL PID= 0x0000
      DCMD VBH SDI DETAIL DID/SDID= 0x0000
      DCMD VBH SDI DETAIL StreamId= 0x0000
      DCMD VBH SDI DETAIL Field 1 Line= 0
      DCMD VBH SDI DETAIL Field 2 Line= 0
      DCMD VBH SDIALT DETAIL --Captions----
      DCMD VBH SDIALT DETAIL Enable= TRUE
      DCMD VBH SDIALT DETAIL Insert Line= 19
      DCMD VBH SDIALT DETAIL Present= FALSE
      DCMD VBH SDIALT DETAIL Count= 0
      DCMD VBH SDIALT DETAIL 608 Len= 0
      DCMD VBH SDIALT DETAIL 708 Len= 0
      DCMD VBH SDIALT DETAIL DID/SDID= 0x0000
      DCMD VBH SDIALT DETAIL 3:2 Pulldown= FALSE
      DCMD VBH SDIALT DETAIL Seq Cnt= 0
      DCMD VBH SDIALT DETAIL Cdp Pkt Size= 0
      DCMD VBH SDIALT DETAIL --Afd----
      DCMD VBH SDIALT DETAIL Enable= FALSE
      DCMD VBH SDIALT DETAIL Insert Line= 0
      DCMD VBH SDIALT DETAIL Present= FALSE
      DCMD VBH SDIALT DETAIL DID/SDID= 0x0000
      DCMD VBH SDIALT DETAIL Active Fmt Flg= 0
      DCMD VBH SDIALT DETAIL Afd Code= 0x00
      DCMD VBH SDIALT DETAIL AR Flag= 0
      DCMD VBH SDIALT DETAIL Bar Data Top= 0
      DCMD VBH SDIALT DETAIL Bar Data Btm= 0
      DCMD VBH SDIALT DETAIL Bar Data Left= 0
      DCMD VBH SDIALT DETAIL Bar Data Right= 0
      DCMD VBH SDIALT DETAIL --VITC----
      DCMD VBH SDIALT DETAIL Enable= TRUE
      DCMD VBH SDIALT DETAIL Present= FALSE
      DCMD VBH SDIALT DETAIL PID= 0x0000
      DCMD VBH SDIALT DETAIL DID/SDID= 0x0000
      DCMD VBH SDIALT DETAIL StreamId= 0x0000
      DCMD VBH SDIALT DETAIL Field 1 Line= 0
      DCMD VBH SDIALT DETAIL Field 2 Line= 0

   output e.g:

   {
   "cvbs":
      [
         {
         "type":"captions",
         "_3_2_pulldown":"FALSE",
         "_608_len":"0",
         "_708_len":"0",
         "cdp_pkt_size":"0",
         "count":"0",
         "did_sdid":"0x0000",
         "enable":"TRUE",
         "insert_line":"21",
         "present":"FALSE",
         "seq_cnt":"0"
         },
         {
         "type":"teletext",
         "active_lines":"0x0000",
         "enable":"TRUE",
         "pid":"0x0000",
         "present":"FALSE"
         }
      ],
   "sdi":
      [
         {
         "type":"captions",
         "_3_2_pulldown":"FALSE",
         ...
         ...
         ..
         },
         {
         "type":"vitc",..
         },
         ..
         ..
      ]
   "sdialt":  
      [
         {
         "type":"captions",
         "_3_2_pulldown":"FALSE",
         ...
         ...
         ..
         },
         {...}
         ..
      ]
   }
    */
   var regex = /^\s*DCMD\s+VH\s+(CVBS|SDI|SDIALT)\s+DETAIL\s+(.+)/i;//mater regex..  all lines must follow this regex
   var headerRegex = /^\-+(Captions|Teletext|VITC|Afd)\-+/i; //indicates a header lines..  
   var regDataRegex = /^(.+)= (.+)/i; //indicates a data line.
   var output, detail, type=_NA, property, rawProperty, obj;
   var result = {};
   for(var i=0; i<lines.length; i++)
      {
      if(regex.test(lines[i]))
         {
         output = (lines[i].replace(regex, "$1")).toLowerCase();
         if(result[output]===undefined){result[output]=[];}
         detail = lines[i].replace(regex, "$2");
         if(headerRegex.test(detail))
            {
            type = (detail.replace(headerRegex, "$1")).toLowerCase();
            obj = {};
            obj._type = type;
            result[output].push(obj);
            }
         else if(regDataRegex.test(detail))
            {
            rawProperty = detail.replace(regDataRegex, "$1");
            property = (ToValidVarName(rawProperty)).toLowerCase();
            obj[property] = detail.replace(regDataRegex, "$2");
            }
         else
            {
            LogMyles("Error in DCMD VH parser. Check detail regular expressions");
            }
         }
      else
         {
         LogMyles("Error in DCMD VH parser. Check regular expression");
         }
      }  
   return result; 
   },
   

   
/************************************************************    
 * Parses the ECMD SL API command (Terse).
 ************************************************************/ 
LocalParse_ecmd_sl = function(lines)
   {
   var result = {};
   var line = lines[0]; //only one line is expected.
   //lines e.g "ECMD SL 0 1"
   var regex = /^\s*ECMD\s+SL\s+(\d+)\s+(\d+)\s*/i;
   if(regex.test(line))
      {
      result["clksrc"] = parseInt(line.replace(regex, "$1"), 10);
      result["ecc"] = parseInt(line.replace(regex, "$2"), 10);
      }
   else
      {
      LogMyles("Error in ECMD SL parser.");
      }
   
   return result;
   },
   
LocalParse_ecmd0_lde = function(lines)
   {
   var result = {};
   var line = lines[0]; //only one line is expected.
   //line e.g "ECMD0 LDE TTX0 LangTTX0= eng"
   var regex = /^\s*ECMD(\d+)?\s+LDE\s+TTX0\s+LangTTX0=\s+(\w+)\s*/i;
   if(regex.test(line))
      {
      result.ttx0 = line.replace(regex, "$2");
      }
   else
      {
      LogMyles("Error in ECMD0 LDE parser.");
      }
   
   return result;
   },
   
LocalParse_ecmd1_lde = function(lines)
   {
   return LocalParse_ecmd0_lde(lines);
   },
   
LocalParse_ecmd0_tx = function(lines)
   {
   var result = [];
   //line e.g "ECMD0 LDE LangTTX0= eng"
   var regex = /^\s*ECMD(\d+)?\s+TX\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/i;
   for(var i=0; i<lines.length; i++)
      {
      var line = lines[i];   
      if(regex.test(line))
         {
         var idx = parseInt(line.replace(regex, "$2"), 10);
         result[idx] =
            {
            "type":                 parseInt(line.replace(regex, "$3"), 10),
            "magazine_number":      parseInt(line.replace(regex, "$4"), 10),
            "page_number":          parseInt(line.replace(regex, "$5"), 10)
            };
         }
      else
         {
         LogMyles("Error in ECMD0|1 TX parser.");
         }
      }
   return result;
   },
   
LocalParse_ecmd1_tx = function(lines)
   {
   return LocalParse_ecmd0_tx(lines);
   },
   
LocalParse_ecmd0_p5 = function(lines)
   {
   var result = {};
   var line = lines[0]; //only one line is expected.
   //lines e.g "ECMD0 P5 01 FFFFE"
   var regex = /^\s*ECMD(\d+)?\s+P5\s+(\d+)\s+([0-9a-f]+)\s*/i;
   if(regex.test(line))
      {
      result.mode = parseInt(line.replace(regex, "$2"), 10);
      result.line_en = parseInt(line.replace(regex, "$3"), 16);
      }
   else
      {
      LogMyles("Error in ECMD0|1 P5 parser.");
      }
   
   return result;
   },
   
LocalParse_ecmd1_p5 = function(lines)
   {
   return LocalParse_ecmd0_p5(lines);
   },
   
LocalParse_ecmd_q1_aux = function(lines)
   {
   var result = {};
   /* ECMD0 Q1 1920x1080 29i 18.56M
    * ECMD0 Q1 1280x 720 59p 18.34M
    * ECMD0 Q1 1920x1080 30i 18.56M
    * ECMD0 Q1 1DD 224k 1DD  Off 48 (NOTE GE 06/14/2010: This line is currently ignored). 
    *
    * ECMD0 Q1 No Video Detected !!
    */
   var topRegex = /^\s*(ECMD[\d])\s+Q1\s+(\d+)\s*x\s*(\d+)\s+(\d{1,2}[a-z])\s+([\d\.]+[a-z])\s*/i;
   var line1NoVideoRegex = /^\s*(ECMD[\d])\s+Q1\s+No Video Detected !!\s*/i; //line 1 of Q1 response
   var cmdh;
   for(var i=0; i<lines.length; i++)
      {
      
      if(topRegex.test(lines[i]))
         {
         result = 
            {
            hsize:   parseInt(lines[i].replace(topRegex, "$2"), 10),
            vsize:   parseInt(lines[i].replace(topRegex, "$3"), 10),
            frate:   lines[i].replace(topRegex, "$4"),
            tmr:     lines[i].replace(topRegex, "$5")
            };
         break;
         }
      else if(line1NoVideoRegex.test(lines[i]))
         {//No video detected
         result  = {"hsize": null, "vsize": null, "frate": _NA, "tmr": _NA};
         break;
         }
      }
   return result;
   },
   
LocalParse_ecmd0_q1 = function(lines)
   {
   return LocalParse_ecmd_q1_aux(lines);
   },
   
LocalParse_ecmd1_q1 = function(lines)
   {
   return LocalParse_ecmd_q1_aux(lines);
   },
   
/******************************************
 * Parses the SYSD DT API command (Terse).
 *******************************************/
LocalParse_sysd_dt = function(lines)
   {
   var result = [];
   /*
    * sysd dt 10/24/11 15:16:02 /media/hd0/dvc/prfAdtecHDTV2_10242011_141422.DVC
    * sysd dt 10/21/11 16:53:32 /media/hd0/dvc/prftest1.DVC
   */
   
   var regex = /^\s*SYSD\s+DT\s+[\d+\/\d+\/\d+\s+\d+\:\d+\:\d+\s+]*([\w\/\.]+)[\s+\d+\/\d+\/\d+\s+\d+\:\d+\:\d+]*\s*/i;
   var profileRegex = /^prf(\w+)/;
   for(var i=0; i<lines.length; i++)
      {
      if(regex.test(lines[i]))
         {
         var filepath = lines[i].replace(regex, "$1");
         var basename = GetFileBasename(filepath);
         var ext = GetFileExtension(filepath);
         if((ext.toUpperCase()=="DVC") && (profileRegex.test(basename)))
            {
            result.push(basename.replace(profileRegex, "$1"));
            }
         else
            {
            LogMyles("Invalid entry in SYSD DT parser.");
            }
         }
      else
         {
         LogMyles("Error in local SYSD DT parser.");
         }
      }
   
   return result;
   },
   
/******************************************
 * Parses the SYSD NAME API command (Terse).
 *******************************************/    
LocalParse_sysd_fe = function(lines)
   {
   /*
    * response e.g
    * SYSD FE 29D4118C447F0F08 P
    * SYSD FE 20100318CF800092 T
    * SYSD FE 00 0000 TESTFEA
    * SYSD FE 00 0000 MP4-CHR-422E
    * SYSD FE 00 0000 MP4-CHR-420E
    * SYSD FE 01 0000 MP2-BASE
    * SYSD FE 01 0000 PDEN81
    * SYSD FE 01 0000 AUD-EXP
    * SYSD FE 00 0000 3D-SYNC-ENC
    */
   var result = {"p": null, "t": null, "features":[]};
   var keyRegex = /^\s*SYSD\s+FE\s+([\da-f]+)\s+([pt])\s*/i;
   var regex = /^\s*SYSD\s+FE\s+(\d+)\s+(\d+)\s+([\w\-]+)\s*/i;
   for(var i=0; i<lines.length; i++)
      {
      if(keyRegex.test(lines[i]))
         {
         result[(lines[i].replace(keyRegex, "$2")).toLowerCase()] = lines[i].replace(keyRegex, "$1"); 
         }
      else if(regex.test(lines[i]))
         {
         var name = lines[i].replace(regex, "$3");
         if(name!="TestFea") //exclude Test feature from the response object
            {
            result.features.push(
               {
               "state":          parseInt(lines[i].replace(regex, "$1"), 10), //0=Disabled, 1=Enabled
               "daysRemaining":  parseInt(lines[i].replace(regex, "$2"), 10), //999=Never
               "name":           name
               });
            }
         }
      else
         {
         LogMyles("Error in SYSD_FE Local parser for line \"" + lines[i] + "\"");
         }
      }
   return result;
   },
   
/******************************************
 * Parses the SYSD NAME API command (Terse).
 *******************************************/    
LocalParse_sysd_na = function(lines)
   {
   var result = null;
   var line = lines[0]; //only one line is expected.
   //lines e.g "SYSD NA <unit name>"
   var regex = /^\s*SYSD\s+NA\s+([\s\-\w]+)\s*/i;
   if(regex.test(line))
      {
      result = line.replace(regex, "$1");
      }
   else
      {
      LogMyles("Error in local SYSD NA parser.");
      }
   
   return result;
   },
   
/******************************************
 * Parses the SYSD BI (BOARDSINFO) API command (Terse).
 *******************************************/    
LocalParse_sysd_bi = function(lines)
   {
   var result = [];
   /*lines e.g 
    * SYSD BI 2  HQ10  "PC81 ver 1.0"
    * SYSD BI 0   QMOD  "PC82_ver_1.1"
    */
   var regex = /^\s*SYSD\s+BI\s+(\d+)\s+(\w+)\s+"([\w\s\.]+)"\s*/i;
   for(var i=0; i<lines.length; i++)
      {
      if(regex.test(lines[i]))
         {
         result.push( 
            {
            "slot": parseInt(lines[i].replace(regex, "$1"), 10),
            "id":   lines[i].replace(regex, "$2"),
            "name": lines[i].replace(regex, "$3")
            });
         }
      else
         {
         LogMyles("Parse error in SYSD BI API command.  Line:\"" + lines[i] + "\"");
         }
      }
   
   return result;
   },

/***************************************************
 * Parses the SYSD PROFILE API command.
 ***************************************************/   
LocalParse_sysd_profile = function(lines)
   {
   /*
    * 
    response e.g:
      sysd profile list t1
      sysd profile list t2
      sysd profile list t3
      sysd profile list t4
   */
   var listRegex = /^\s*SYSD\s+PROFILE\s+LIST\s+(\w+)\s*/i;
   var statusRegex = /^\s*SYSD\s+PROFILE\s+STATUS\s+(\w+)\s*/i;
   var result = {"list": [], "status": null};
   for(var i=0; i<lines.length; i++)
      {
      if(listRegex.test(lines[i]))
         {
         result.list.push({"name": lines[i].replace(listRegex, "$1")});
         }
      else if(statusRegex.test(lines[i]))
         {
         result.status = lines[i].replace(statusRegex, "$1").toUpperCase();
         }
      }
   return result;
   
   },   

LocalParse_sysd_ss = function(lines)
   {
//   Response e.g:  SYSD SS 0 STATE 0
   var stateRegex = /\s*SYSD\s+SS\s+(\d+)\s+STATE\s+(\d+)/i;
   var result = [];
   for(var i=0; i<lines.length; i++)
      {
      var line = lines[0];
      if(stateRegex.test(line))
         {
         var idx = parseInt(line.replace(stateRegex, "$1"), 10);
         if(result[idx]===undefined){result[idx] = {};}
         result[idx].state = parseInt(line.replace(stateRegex, "$2"), 10);
         }
      else
         {
         LogMyles("Unable to parse line \""+line+"\"");
         }
      }
   return result;
   },
/***************************************************
 * Parses the SYSD SYSTEMPROFILE API command.
 ***************************************************/   
LocalParse_sysd_systemprofile = function(lines)
   {
   /*
    * 
    response e.g:
      sysd systemprofile list t1
      sysd systemprofile list t2
      sysd systemprofile list t3
      sysd systemprofile list t4
   */
   var listRegex = /^\s*SYSD\s+SYSTEMPROFILE\s+LIST\s+(\w+)\s*/i;
   var statusRegex = /^\s*SYSD\s+SYSTEMPROFILE\s+STATUS\s+(\w+)\s*/i;
   var result = null;
   for(var i=0; i<lines.length; i++)
      {
      if(listRegex.test(lines[i]))
         {
         if(result===null){result = [];}
         result.push({"name": lines[i].replace(listRegex, "$1")});
         }
      else if(statusRegex.test(lines[i]))
         {
         result = {"ready": (lines[i].replace(statusRegex, "$1").toUpperCase() == "READY")};
         break;
         }
      }
   return result;
   
   },
   
/*****************************************************
 * Parses the SYSD UG API command.
 *****************************************************/
LocalParse_sysd_ug = function(lines)
   {
   /*
    Response e.g (Modulators) NTC7029 30052527 45
    Response e.g (Newtec Demod) NTC/7044/AB DVB Demodulator 30015081 25 1.21
    
    */
   var result = null;
   var line = lines[0]; //only one line is expected in the response
   var enRegex = /^\s*SYSD\s+UG\s+(\w+)\s+([\da-f]+)\s+(\d+)\s*/i;
   var rdNtc7044Regex = /^\s*SYSD\s+UG\s+"([\w\/\s]+)"\s+([\da-f]+)\s+(\d+)\s+([\d\.]+)\s*/i;  //BOARD_ID=NTC/7044/AB DVB Demodulator
   var hardwareErrRegex =  /^\s*SYSD\s+UG\s+2650\s*$/i;
   var rdAdtecRegex = /^\s*SYSD\s+UG\s+(\w+)\s*$/i;
   var parseError = true; //assume parse error
   
   if(IsENXX() && enRegex.test(line))
      {
      parseError = false;
      result = 
         {
         "boardId": line.replace(enRegex, "$1"),
         "serial": line.replace(enRegex, "$2"),
         "license": line.replace(enRegex, "$3")
         };
      }
   else if (GetProductId() == _PRODUCT.RD60.id)
      {
      if(rdNtc7044Regex.test(line))
         {
         parseError = false;
         result = 
            {
            "boardId": line.replace(rdNtc7044Regex, "$1"),
            "serial": line.replace(rdNtc7044Regex, "$2"),
            "license": line.replace(rdNtc7044Regex, "$3"),
            "swVersion": line.replace(rdNtc7044Regex, "$4")
            };
         }
      else if(hardwareErrRegex.test(line))
         {
         result = 
            {
            "boardId": "N/A",
            "serial": "N/A",
            "license": "N/A",
            "swVersion": "N/A"
            }; 
         }
      else if(rdAdtecRegex.test(line))
         {
         parseError = false;
         result =   {"boardId": line.replace(rdAdtecRegex, "$1")};
         }
      }
   
   if(parseError)
      {
      LogMyles("Parse error in SYSD UG API command.  Line:\"" + line + "\"");
      }
   
   return result;
   },

/*****************************************************
 * Parses the SYSD MF API command.
 *****************************************************/
LocalParse_sysd_mf = function(lines)
   {
   var regex = /^SYSD\s+MF\s+([A-Z\-0-9]+)\s+([A-Z0-9]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([A-Z0-9]+)\s+([0-9\-\:\@]+)\s+([0-9\-\:\@]+)/i;
   var line = lines[0]; // only one line
   var result = null;
   if (regex.test(line))
      {
      result = 
         {
         "productName": line.replace(regex, "$1"),
         "partName": line.replace(regex, "$2"),
         "date": line.replace(regex, "$3") + line.replace(regex, "$4") + line.replace(regex, "$5"),
         "serial": line.replace(regex, "$6"),
         "microMonitorVersion": line.replace(regex, "$7"),
         "cpldVersion": line.replace(regex, "$8")
         };
      }
   else
      {
      LogMyles("Parse error in SYSD MF API command.  Line:\"" + line + "\"");
      }
   return result;
   },
   
LocalParse_ecmd_ton = function(lines)
   {
   var regex = /^ECMD(\d+)?\s+TablesOn=\s+(\w+)/i;
   var line = lines[0]; // only one line
   var result = null;
   if (regex.test(line))
      {
      result = line.replace(regex, "$2");
      }
   return result;
   },
   
LocalParse_ecmd0_ton = function(lines)
   {
   return LocalParse_ecmd_ton(lines);
   },
   
LocalParse_ecmd1_ton = function(lines)
   {
   return LocalParse_ecmd_ton(lines);
   }
   ;
/*****************************************************************************
* @file
* @author  Original:      German Escallon
* @author  Contributors:  
* @date    Created:       Aug 3, 2010
* @date    Last Edit:     $Date$ by $Author$
* Description: This file handles the mod output tab.
*****************************************************************************/ 


/*********************************************************
 * MODULATOR CALCULATOR Constructor
 ********************************************************/
MOD_CALC = function
   (
   inWebUi, //!< Boolean (optional). If true, indicates that calc is embedded in Web UI.  Default: false. 
   exportCallback //Callback function to invoke when the export event occurs.  This callback is used to update the Web UI fields based on the new parameters set by the calculator
   )  //constructor
   {
   if(inWebUi)
      { 
      this.inWebUi = true;
      }
   else 
      { 
      this.inWebUi = false;
      }
   if(typeof(exportCallback)=="function") 
      {
      this.exportCallback = exportCallback;
      }
   // TODO
   this.ClearMessage = function   ()
      {
      if($(this.MOD_CALC_MSG_ID))  ///avoid execution if code has not rendered.
         {
         DomSetElementColor($(this.MOD_CALC_MSG_ID), _ADTCOLOR.BLACK);
         $(this.MOD_CALC_MSG_ID).innerHTML = '';
         }
      };

   //TODO
   this.SetMessage= function    (     msg,      color      )
      {
      if((color===undefined)||(color===null))
       {
       color = _ADTCOLOR.BLACK;
       }
      if($(this.MOD_CALC_MSG_ID))  ///avoid execution if code has not rendered.
         {
         DomSetElementColor($(this.MOD_CALC_MSG_ID), color);
         $(this.MOD_CALC_MSG_ID).innerHTML = msg;
         setTimeout(this.ClearMessage, _DEFAULT_INFO_MSG_TIMEOUT);
         }
      };
      
    //TODO 
   this.SetWarning = function(   msg,     elLabelId    )
      {
      this.SetMessage(msg, _ADTCOLOR.GOLD);
      DomSetElementColor($(elLabelId),  _ADTCOLOR.GOLD);
      setTimeout(this.ClearMessage, _DEFAULT_INFO_MSG_TIMEOUT);
      };

   //TODO
   this.ResetWarnings =  function()
      {
      this.ClearMessage();
      var labels = $(this.MOD_CALCULATOR_MAIN_DIV).getElementsByTagName("label");
      for(var i=0; i<labels.length; i++)
         {
         DomSetElementColor(labels[i], _ADTCOLOR.BLACK);
         }
      };

   //TODO
   this.GetInputLabelId =  function
      (
      inputObj
      )
      {
      var result = '';
      
      var inId = inputObj.id;
      var inputRegex = /Input$/;
      var selectRegex = /Select$/;
      if(inputRegex.test(inId))
         {
         result = inId.replace("Input","Lbl");
         }
      else if(selectRegex.test(inId))
         {
         result = inId.replace("Select","Lbl");
         }
      return result;
      };
   
   /******************************************************************************************
   * Exports New Settings to the WEB UI interface.
   * returns an object w/ the new parameters.
   ******************************************************************************************/
   this.ExportToWebUI =   function
      (
      )
      {
      var usePilot;
      switch($("newUsePilotsSelect").value)
         {
         case "Y":
            usePilot = true;
            break;
         case "N":
            usePilot = false;
            break;
         case "R":
            var newModeNum = parseInt($("newModModeSelect").value, 10);
            if(this.MODFORMAT[newModeNum].BITRATERP == this.MODFORMAT[newModeNum].BITRATEWP)
               {//recommended use of pilots detected 
               usePilot = true;
               }
            else
               {
               usePilot = false;
               }
            break;
         default: //if use of pilots cannot be determined, false is assumed
            usePilot = false;
            break;
         }

         var result = 
            {
            "MODTYPE":  this.GetNewtecModType($("newModModeSelect").value),
            "MODFORMAT": this.GetNewtecModFormat($("newModModeSelect").value),
            "SYMBOLRATE": parseFloat($("newSymRateInput").value, 10),
            "ROLLOFF":  parseInt($("newRolloffSelect").value, 10),
            "USEPILOT": usePilot   
            };
         this.exportCallback(result);

         this.modCalcPanel.hide();
      };

   //TODO
   this.GetNewtecModFormat = function (modFormatVal)
      {
      var result = -1;
      switch (parseInt(modFormatVal, 10))
         {
         case 16: result = -1; break;//TODO:  Unsupported mod mode..  Not found in Excel spreadsheet
      
         case 1: result = 11; break;

         case 2: result = 12; break;//DVB-S QPSK (FEC 2/3)
         case 3: result = 13; break;//DVB-S QPSK (FEC 3/4)
         case 4: result = 15; break;//DVB-S QPSK (FEC 5/6)
         case 5: result = 17; break;//DVB-S QPSK (FEC 7/8)
 
         case 13: result = 21; break; //QPSK_1/4
         case 14: result = 22; break; //QPSK_1/3
         case 15: result = 23; break; //QPSK_2/5
         case 17: result = 24; break; //QPSK_3/5
         case 20: result = 25; break; //QPSK_4/5
         case 22: result = 26; break; //QPSK_8/9
         case 23: result = 27; break; //QPSK_9/10

         case 24: result = 81; break; //8PSK_3/5
         case 25: result = 82; break; //8PSK_2/3
         case 26: result = 83; break; //8PSK_3/4
         case 27: result = 85; break; //8PSK_5/6
         case 28: result = 88; break; //8PSK_8/9
         case 29: result = 89; break; //8PSK_9/10

         case 11: result = 63; break; //16QAM_3/4
         case 12: result = 67; break; //16QAM_7/8
         
         case 30: //16APSK_2/3
         case 36: result = 42; break;//16APSK_2/3
     
         case 31: //QPSK (FEC 3/4)
         case 37: result = 43; break;//QPSK (FEC 3/4)

         case 32: //16APSK_4/5
         case 38: result = 44; break;//16APSK_4/5
         
         case 33: //16APSK_5/6
         case 39: result = 45; break;//16APSK_5/6
   
         case 34: //16APSK_8/9
         case 40: result = 48; break;//16APSK_8/9
   
         case 35: //16APSK_9/10
         case 41: result = 49; break;//16APSK_9/10
         
         case 42: //32APSK_3/4
         case 47: result = 53; break;//32APSK_3/4
         
         case 43: //32APSK_4/5
         case 48: result = 54; break;//32APSK_4/5
   
         case 44: //32APSK_5/6
         case 49: result = 55; break;//32APSK_5/6
         
         case 45: //32APSK_8/9
         case 50: result = 58; break;//32APSK_8/9
         
         case 46: //32APSK_9/10
         case 51: result = 59; break;//32APSK_9/10
   
         default: result = -1; break; //unknown or invalid mod mode
 
         }
      return result;
      };
      
      
   //TODO
   this.GetNewtecModType = function (modFormatVal)
      {
      var result = -1;
      switch(parseInt(modFormatVal, 10))
         {
         case 1:
         case 2:
         case 3:
         case 4:
         case 5:
            result = _MODTYPE.DVB_S;
            break;
            
         case 6:
         case 7:
         case 8: 
         case 9:
         case 10:
         case 11:
         case 12://DVB-DSNG is not supported by Adtec's EN-xx
            result = _MODTYPE.DVB_DSNG;
            break;
         
         case 13:
         case 14:
         case 15:
         case 16:
         case 17:
         case 18:
         case 19:
         case 20:
         case 21:
         case 22:
         case 23:
         case 24:
         case 25:
         case 26:
         case 27:
         case 28:
         case 29:
         case 30:
         case 31:
         case 32:
         case 33:
         case 34:
         case 35:
         case 36:
         case 37:
         case 38:
         case 39:
         case 40:
         case 41:
         case 42:
         case 43:
         case 44:
         case 45:
         case 46:
         case 47:
         case 48:
         case 49:
         case 50:
         case 51:
            result = _MODTYPE.DVB_S2;
            break;
         
         }
      return result;
      };
      

      
   //check if user app provided a container id
   this.containerId = "modCalcContainerId";
   //checks if an element w/ the container id already exists in the document. 
   if(($(this.containerId) === undefined) ||($(this.containerId) ===null) )
      { //create container element in the DOMif it doesn't exist
      var calcDiv = document.createElement("div");
      calcDiv.setAttribute('id', this.containerId);
      document.body.appendChild(calcDiv);
      } 
   
   };
   

MOD_CALC.prototype = 
   {
   //constants
   EXPORTBUTTONID: "exportToWebUiId",
   PRECISION: 4,
   ROLLOFFVALARRAY:[-1, 35, 25, 20], 
   MOD_CALC_MSG_ID: "modCalcMsg", 
   MOD_CALCULATOR_MAIN_DIV: "modCalcMainDiv", 
   MOD_CALCULATOR_CLASS: "modCalcClass", //NOTE GE 10/25/2010: This name must be in sync w/ css.  see myles.css.
   MODFORMAT: 
      [
         {"CSAT":-1,     "BITRATENP":-1,     "BITRATEWP":-1,     "BITRATERP":-1 }, //dummy placeholder..array is 0 based, but table is 1based.
         {"CSAT":2.6900, "BITRATENP":0.9216, "BITRATEWP":0.9216, "BITRATERP":0.9216 }, 
         {"CSAT":4.3600, "BITRATENP":1.2288, "BITRATEWP":1.2288, "BITRATERP":1.2288 }, 
         {"CSAT":5.4600, "BITRATENP":1.3824, "BITRATEWP":1.3824, "BITRATERP":1.3824 }, 
         {"CSAT":6.5300, "BITRATENP":1.5359, "BITRATEWP":1.5359, "BITRATERP":1.5359 }, 
         {"CSAT":7.2400, "BITRATENP":1.6127, "BITRATEWP":1.6127, "BITRATERP":1.6127 }, 
         {"CSAT":8.1200, "BITRATENP":1.8431, "BITRATEWP":1.8431, "BITRATERP":1.8431 }, 
         {"CSAT":10.4200, "BITRATENP":2.3039, "BITRATEWP":2.3039, "BITRATERP":2.3039 }, 
         {"CSAT":11.2200, "BITRATENP":2.4575, "BITRATEWP":2.4575, "BITRATERP":2.4575 }, 
         {"CSAT":11.4300, "BITRATENP":2.7647, "BITRATEWP":2.7647, "BITRATERP":2.7647 }, 
         {"CSAT":13.1200, "BITRATENP":3.2255, "BITRATEWP":3.2255, "BITRATERP":3.2255 }, 
         {"CSAT":13.9900, "BITRATENP":2.7647, "BITRATEWP":2.7647, "BITRATERP":2.7647 }, 
         {"CSAT":15.6800, "BITRATENP":3.2255, "BITRATEWP":3.2255, "BITRATERP":3.2255 }, 
         {"CSAT":-2.3500, "BITRATENP":0.4902, "BITRATEWP":0.4777, "BITRATERP":0.4777 }, 
         {"CSAT":-1.2400, "BITRATENP":0.6564, "BITRATEWP":0.6396, "BITRATERP":0.6396 }, 
         {"CSAT":-0.3000, "BITRATENP":0.7919, "BITRATEWP":0.7716, "BITRATERP":0.7716 }, 
         {"CSAT":1.0000, "BITRATENP":0.9889, "BITRATEWP":0.9635, "BITRATERP":0.9635 }, 
         {"CSAT":2.2300, "BITRATENP":1.1883, "BITRATEWP":1.1578, "BITRATERP":1.1578 }, 
         {"CSAT":3.1000, "BITRATENP":1.3223, "BITRATEWP":1.2883, "BITRATERP":1.3223 }, 
         {"CSAT":4.0300, "BITRATENP":1.4875, "BITRATEWP":1.4493, "BITRATERP":1.4875 }, 
         {"CSAT":4.6800, "BITRATENP":1.5872, "BITRATEWP":1.5465, "BITRATERP":1.5872 }, 
         {"CSAT":5.1800, "BITRATENP":1.6547, "BITRATEWP":1.6122, "BITRATERP":1.6547 }, 
         {"CSAT":6.2000, "BITRATENP":1.7665, "BITRATEWP":1.7212, "BITRATERP":1.7665 }, 
         {"CSAT":6.4200, "BITRATENP":1.7886, "BITRATEWP":1.7428, "BITRATERP":1.7886 }, 
         {"CSAT":5.5000, "BITRATENP":1.7800, "BITRATEWP":1.7343, "BITRATERP":1.7343 }, 
         {"CSAT":6.6200, "BITRATENP":1.9806, "BITRATEWP":1.9298, "BITRATERP":1.9298 }, 
         {"CSAT":7.9100, "BITRATENP":2.2281, "BITRATEWP":2.1710, "BITRATERP":2.1710 }, 
         {"CSAT":9.3500, "BITRATENP":2.4786, "BITRATEWP":2.4150, "BITRATERP":2.4150 }, 
         {"CSAT":10.6900, "BITRATENP":2.6460, "BITRATEWP":2.5782, "BITRATERP":2.6460 }, 
         {"CSAT":10.9800, "BITRATENP":2.6792, "BITRATEWP":2.6105, "BITRATERP":2.6792 }, 
         {"CSAT":8.9700, "BITRATENP":2.6372, "BITRATEWP":2.5696, "BITRATERP":2.5696 }, 
         {"CSAT":10.2100, "BITRATENP":2.9667, "BITRATEWP":2.8907, "BITRATERP":2.8907 }, 
         {"CSAT":11.0300, "BITRATENP":3.1656, "BITRATEWP":3.0845, "BITRATERP":3.0845 }, 
         {"CSAT":11.6100, "BITRATENP":3.3002, "BITRATEWP":3.2156, "BITRATERP":3.2156 }, 
         {"CSAT":12.8900, "BITRATENP":3.5231, "BITRATEWP":3.4328, "BITRATERP":3.4328 }, 
         {"CSAT":13.1300, "BITRATENP":3.5673, "BITRATEWP":3.4759, "BITRATERP":3.4759 }, 
         {"CSAT":10.0500, "BITRATENP":2.6372, "BITRATEWP":2.5696, "BITRATERP":2.5696 }, 
         {"CSAT":11.2900, "BITRATENP":2.9667, "BITRATEWP":2.8907, "BITRATERP":2.8907 }, 
         {"CSAT":12.1100, "BITRATENP":3.1656, "BITRATEWP":3.0845, "BITRATERP":3.0845 }, 
         {"CSAT":12.6900, "BITRATENP":3.3002, "BITRATEWP":3.2156, "BITRATERP":3.2156 }, 
         {"CSAT":13.9700, "BITRATENP":3.5231, "BITRATEWP":3.4328, "BITRATERP":3.4328 }, 
         {"CSAT":14.2100, "BITRATENP":3.5673, "BITRATEWP":3.4759, "BITRATERP":3.4759 }, 
         {"CSAT":12.7300, "BITRATENP":3.7033, "BITRATEWP":3.6083, "BITRATERP":3.6083 }, 
         {"CSAT":13.6400, "BITRATENP":3.9516, "BITRATEWP":3.8502, "BITRATERP":3.8502 }, 
         {"CSAT":14.2800, "BITRATENP":4.1195, "BITRATEWP":4.0139, "BITRATERP":4.0139 }, 
         {"CSAT":15.6900, "BITRATENP":4.3979, "BITRATEWP":4.2851, "BITRATERP":4.2851 }, 
         {"CSAT":16.0500, "BITRATENP":4.4530, "BITRATEWP":4.3388, "BITRATERP":4.3388 }, 
         {"CSAT":14.7750, "BITRATENP":3.7033, "BITRATEWP":3.6083, "BITRATERP":3.6083 }, 
         {"CSAT":15.6850, "BITRATENP":3.9516, "BITRATEWP":3.8502, "BITRATERP":3.8502 }, 
         {"CSAT":16.3250, "BITRATENP":4.1195, "BITRATEWP":4.0139, "BITRATERP":4.0139 }, 
         {"CSAT":17.7350, "BITRATENP":4.3979, "BITRATEWP":4.2851, "BITRATERP":4.2851 }, 
         {"CSAT":18.0950, "BITRATENP":4.4530, "BITRATEWP":4.3388, "BITRATERP":4.3388 }
      ],
      
      
   //variables
   modCalcPanel: null,
   inWebUi: false,
   reverseCalc: false
   
   
   };

/******************************************************************************************
 * Renders Modulation Calculator HTML markup, 
 * sets up event listeners, and leaves the object 
 * it in a ready state to be displayed
 ******************************************************************************************/
MOD_CALC.prototype.Render = function()
   {
   
   var modCalcPnlCfg = 
      {
      width: "725px",
      autofillheight: "body", 
//      height: "550px",
      fixedcenter: true, 
      underlay:"matte",
      modal: false, 
      close:true,     
      visible:false,  //hidden by default
      draggable:true 
      };
 
   var calcMarkup = ''
      +   '<div id="' + this.MOD_CALCULATOR_MAIN_DIV + '" class="' + this.MOD_CALCULATOR_CLASS + '">'
      +   '<p><span id="' + this.MOD_CALC_MSG_ID + '"></span></p>'
      +   '<table>'
      +   '<tr>'
      +      '<td><b><label id="currModModeLbl">Current Modulation Format:</label></b></td>'
      +      '<td><select id="currModModeSelect">' 
      +         '<optgroup label="DVB-S QPSK">'
      +         '<option value="1">DVB-S QPSK (FEC 1/2)</option>'
      +         '<option value="2">DVB-S QPSK (FEC 2/3)</option>'
      +         '<option value="3">DVB-S QPSK (FEC 3/4)</option>'
      +         '<option value="4">DVB-S QPSK (FEC 5/6)</option>'
      +         '<option value="5">DVB-S QPSK (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-DSNG 8PSK">'
      +         '<option value="6">DVB-DSNG 8PSK (FEC 2/3)</option>'
      +         '<option value="7">DVB-DSNG 8PSK (FEC 5/6)</option>'
      +         '<option value="8">DVB-DSNG 8PSK (FEC 8/9)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="9">DVB-DSNG 16QAM (FEC 3/4)</option>'
      +         '<option value="10">DVB-DSNG 16QAM (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="11">DVB-DSNG 16QAM (FEC 3/4)</option>'
      +         '<option value="12">DVB-DSNG 16QAM (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-S2 QPSK">'
      +         '<option value="13">DVB-S2 QPSK (FEC 1/4)</option>'
      +         '<option value="14">DVB-S2 QPSK (FEC 1/3)</option>'
      +         '<option value="15">DVB-S2 QPSK (FEC 2/5)</option>'
      +         '<option value="16">DVB-S2 QPSK (FEC 1/2)</option>'
      +         '<option value="17">DVB-S2 QPSK (FEC 3/5)</option>'
      +         '<option value="18">DVB-S2 QPSK (FEC 2/3)</option>'
      +         '<option value="19">DVB-S2 QPSK (FEC 3/4)</option>'
      +         '<option value="20">DVB-S2 QPSK (FEC 4/5)</option>'
      +         '<option value="21">DVB-S2 QPSK (FEC 5/6)</option>'
      +         '<option value="22">DVB-S2 QPSK (FEC 8/9)</option>'
      +         '<option value="23">DVB-S2 QPSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-D2 8PSK">'
      +         '<option value="24">DVB-S2 8PSK (FEC 3/5)</option>'
      +         '<option value="25">DVB-S2 8PSK (FEC 2/3)</option>'
      +         '<option value="26">DVB-S2 8PSK (FEC 3/4)</option>'
      +         '<option value="27">DVB-S2 8PSK (FEC 5/6)</option>'
      +         '<option value="28">DVB-S2 8PSK (FEC 8/9)</option>'
      +         '<option value="29">DVB-S2 8PSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="30">DVB-S2 16APSK (FEC 2/3)</option>'
      +         '<option value="31">DVB-S2 16APSK (FEC 3/4)</option>'
      +         '<option value="32">DVB-S2 16APSK (FEC 4/5)</option>'
      +         '<option value="33">DVB-S2 16APSK (FEC 5/6)</option>'
      +         '<option value="34">DVB-S2 16APSK (FEC 8/9)</option>'
      +         '<option value="35">DVB-S2 16APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="36">DVB-S2 16APSK (FEC 2/3)</option>'
      +         '<option value="37">DVB-S2 16APSK (FEC 3/4)</option>'
      +         '<option value="38">DVB-S2 16APSK (FEC 4/5)</option>'
      +         '<option value="39">DVB-S2 16APSK (FEC 5/6)</option>'
      +         '<option value="40">DVB-S2 16APSK (FEC 8/9)</option>'
      +         '<option value="41">DVB-S2 16APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="42">DVB-S2 32APSK (FEC 3/4)</option>'
      +         '<option value="43">DVB-S2 32APSK (FEC 4/5)</option>'
      +         '<option value="44">DVB-S2 32APSK (FEC 5/6)</option>'
      +         '<option value="45">DVB-S2 32APSK (FEC 8/9)</option>'
      +         '<option value="46">DVB-S2 32APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="47">DVB-S2 32APSK (FEC 3/4)</option>'
      +         '<option value="48">DVB-S2 32APSK (FEC 4/5)</option>'
      +         '<option value="49">DVB-S2 32APSK (FEC 5/6)</option>'
      +         '<option value="50">DVB-S2 32APSK (FEC 8/9)</option>'
      +         '<option value="51">DVB-S2 32APSK (FEC 9/10)</option>'
      +         '</optgroup>'
      + '</select></td>'
      
      
      +      '<td><b><label id="currUsePilotsLbl">Use of Pilots:</label></b></td>'
      +      '<td><select id="currUsePilotsSelect">'
      +           '<option value="R">As Recommended</option>'
      +           '<option value="Y">Yes</option>'
      +           '<option value="N">No</option>'
      +      '</select></td>'
      
      +   '</tr>'
      +   '<tr>'
      +      '<td><b><label id="currSymRateLbl">Current Symbol Rate:</label></b></td>'
      +      '<td><input id="currSymRateInput"></input></td>'
      +      '<td><b><label id="currRolloffLbl">Rolloff:</label></b></td>'
      +      '<td><select id="currRolloffSelect">' 
      +         '<option value="3">20</option>' //must match mod_rolloff.  See mylesUtilities.js
      +         '<option value="2">25</option>' 
      +         '<option value="1">35</option>' 
      +     '</select></td>'
      +   '</tr>'
      +   '<tr>'
      +      '<td><b><label id="currSaturationLbl">Saturation:</label></b></td>'
      +      '<td><select id="saturationSelect">' 
      +         '<option value="SINGLE">Single Saturated Carrier per Transponder</option>'
      +         '<option value="MULTI">Multi Carrier per Transponder</option>'
      +      '</select></td>'
      +   '</tr>'
      +   '<tr><td colspan="4"><hr></hr></td></tr>' //ruler line
      +   '<tr>'
      +      '<td><b><label id="currBitRateLbl">Current Bit Rate:</label></b></td>'
      +      '<td><span id="currBitRateSpan"></span></td>'
      +      '<td><b>Current Occupied Bandwidth:</b></td>'
      +      '<td><span id="currOccBandwidthSpan"></span></td>'
      +   '</tr>'
      +   '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>' //blank line
      +   '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>' //blank line
      +   '<tr>'
      +      '<td><b><label id="newModModeLbl">New Modulation Format:</label></b></td>'
      +      '<td><select id="newModModeSelect">'  
      +         '<optgroup label="DVB-S QPSK">'
      +         '<option value="1">DVB-S QPSK (FEC 1/2)</option>'
      +         '<option value="2">DVB-S QPSK (FEC 2/3)</option>'
      +         '<option value="3">DVB-S QPSK (FEC 3/4)</option>'
      +         '<option value="4">DVB-S QPSK (FEC 5/6)</option>'
      +         '<option value="5">DVB-S QPSK (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-DSNG 8PSK">'
      +         '<option value="6">DVB-DSNG 8PSK (FEC 2/3)</option>'
      +         '<option value="7">DVB-DSNG 8PSK (FEC 5/6)</option>'
      +         '<option value="8">DVB-DSNG 8PSK (FEC 8/9)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="9">DVB-DSNG 16QAM (FEC 3/4)</option>'
      +         '<option value="10">DVB-DSNG 16QAM (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="11">DVB-DSNG 16QAM (FEC 3/4)</option>'
      +         '<option value="12">DVB-DSNG 16QAM (FEC 7/8)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-S2 QPSK">'
      +         '<option value="13">DVB-S2 QPSK (FEC 1/4)</option>'
      +         '<option value="14">DVB-S2 QPSK (FEC 1/3)</option>'
      +         '<option value="15">DVB-S2 QPSK (FEC 2/5)</option>'
      +         '<option value="16">DVB-S2 QPSK (FEC 1/2)</option>'
      +         '<option value="17">DVB-S2 QPSK (FEC 3/5)</option>'
      +         '<option value="18">DVB-S2 QPSK (FEC 2/3)</option>'
      +         '<option value="19">DVB-S2 QPSK (FEC 3/4)</option>'
      +         '<option value="20">DVB-S2 QPSK (FEC 4/5)</option>'
      +         '<option value="21">DVB-S2 QPSK (FEC 5/6)</option>'
      +         '<option value="22">DVB-S2 QPSK (FEC 8/9)</option>'
      +         '<option value="23">DVB-S2 QPSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="DVB-D2 8PSK">'
      +         '<option value="24">DVB-S2 8PSK (FEC 3/5)</option>'
      +         '<option value="25">DVB-S2 8PSK (FEC 2/3)</option>'
      +         '<option value="26">DVB-S2 8PSK (FEC 3/4)</option>'
      +         '<option value="27">DVB-S2 8PSK (FEC 5/6)</option>'
      +         '<option value="28">DVB-S2 8PSK (FEC 8/9)</option>'
      +         '<option value="29">DVB-S2 8PSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="30">DVB-S2 16APSK (FEC 2/3)</option>'
      +         '<option value="31">DVB-S2 16APSK (FEC 3/4)</option>'
      +         '<option value="32">DVB-S2 16APSK (FEC 4/5)</option>'
      +         '<option value="33">DVB-S2 16APSK (FEC 5/6)</option>'
      +         '<option value="34">DVB-S2 16APSK (FEC 8/9)</option>'
      +         '<option value="35">DVB-S2 16APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="36">DVB-S2 16APSK (FEC 2/3)</option>'
      +         '<option value="37">DVB-S2 16APSK (FEC 3/4)</option>'
      +         '<option value="38">DVB-S2 16APSK (FEC 4/5)</option>'
      +         '<option value="39">DVB-S2 16APSK (FEC 5/6)</option>'
      +         '<option value="40">DVB-S2 16APSK (FEC 8/9)</option>'
      +         '<option value="41">DVB-S2 16APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Multi-Carrier per Transponder">'
      +         '<option value="42">DVB-S2 32APSK (FEC 3/4)</option>'
      +         '<option value="43">DVB-S2 32APSK (FEC 4/5)</option>'
      +         '<option value="44">DVB-S2 32APSK (FEC 5/6)</option>'
      +         '<option value="45">DVB-S2 32APSK (FEC 8/9)</option>'
      +         '<option value="46">DVB-S2 32APSK (FEC 9/10)</option>'
      +         '</optgroup>'
               
      +         '<optgroup label="Single Saturated Carrier per Transponder">'
      +         '<option value="47">DVB-S2 32APSK (FEC 3/4)</option>'
      +         '<option value="48">DVB-S2 32APSK (FEC 4/5)</option>'
      +         '<option value="49">DVB-S2 32APSK (FEC 5/6)</option>'
      +         '<option value="50">DVB-S2 32APSK (FEC 8/9)</option>'
      +         '<option value="51">DVB-S2 32APSK (FEC 9/10)</option>'
      +         '</optgroup>'
      + '</select></td>'
      +      '<td><b><label id="newUsePilotsLbl">Use of Pilots:</label></b></td>'
      +      '<td><select id="newUsePilotsSelect">'
      +           '<option value="R">As Recommended</option>'
      +           '<option value="Y">Yes</option>'
      +           '<option value="N">No</option>'
      +      '</select></td>'
      +   '   </tr>'    
      +   '<tr>'
      +      '<td><b><label id="newSymRateLbl">New Symbol Rate:</label></b></td>'
      +      '<td><input id="newSymRateInput"></input></td>'
      +      '<td><b><label id="newRolloffLbl">New Rolloff:</label></b></td>'
      +      '<td><select id="newRolloffSelect">' 
      +         '<option value="3">20</option>' //must match mod_rolloff.  See mylesUtilities.js
      +         '<option value="2">25</option>' 
      +         '<option value="1">35</option>' 
      +     '</select></td>'
      +   '</tr>'
      +   '<tr><td colspan="4"><hr></hr></td></tr>' //ruler line
      
      +   '<tr>'
      +      '<td><b>New Bit Rate:</b></td>'
      +      '<td><span id="newBitRateSpan"></span></td>'
      +      '<td><b><label id="newOccBandwidthLbl">New Occupied Bandwidth:</label></b></td>'
      +      '<td><input id="newOccBandwidthInput"></input></td>'
      +   '</tr>'
      +   '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>' //blank line
      +   '<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>' //blank line
      
      
      +   '<tr>'
      +      '<td><b>Due to Symbol Rate Change:</b></td>'
      +      '<td><span id="marginSymRateChange">1</span></td>'
      +      '<td><b>Due to FEC Change:</b></td>'
      +      '<td><span id="marginFecChange">1</span></td>'
      +   '</tr>'
      +   '<tr>'
      +      '<td><b>Due to Rolloff Change:</b></td>'
      +      '<td><span id="marginRolloffChange">1</span></td>'
      +      '<td><b>Including Power Change:</b></td>'
      +      '<td><span id="marginPowerChange">1</span></td>'
      +   '</tr>'
      +   '<tr>'
      +      '<td><b>Total Change in Link Margin:</b></td>'
      +      '<td><span id="marginTotalChange">1</span></td>'
      +      '<td><b>Total Change in Bit Rate:</b></td>'
      +      '<td><span id="bitRateTotalChange">1</span></td>'
      +   '</tr>'
      +   '<tr>'
      +      '<td><b>Percentage Change in Bit Rate:</b></td>'
      +      '<td><span id="percentageBitRateChange">1</span></td>'
      +      '<td></td><td></td>'
      +   '</table>'
      +   '</div>'
      ;
   if(this.inWebUi)
      {
      calcMarkup += ''
         + '<p><br /><button id="' + this.EXPORTBUTTONID + '">Export</button><br /></p>' 
         ;
      }
 
   this.modCalcPanel = new YAHOO.widget.Panel(this.containerId, modCalcPnlCfg);
 
   //sets panel header
   this.modCalcPanel.setHeader("<b>Adtec Digital Modulation Calculator</b>");
   this.modCalcPanel.setBody('<p>' + calcMarkup + '</p>');
   this.modCalcPanel.render();
   //sets event listeners
   var inputObjs = $(this.MOD_CALCULATOR_MAIN_DIV).getElementsByTagName("input");
   var inputsArray = [];
   
   for(var i=0; i<inputObjs.length; i++)  {   inputsArray[i] = inputObjs[i];   }
   
   for( i=inputsArray.length-1; i>=0; i--)
      {
      switch(inputsArray[i].id)
         {
         case "newSymRateInput"://special cases. These cases must set the reverse flag prior to performing the calculation
         case "newOccBandwidthInput":
            inputsArray.splice(i, 1); //removes input from array
            break;
         default:     break; // take no action
         }
      }
   var selectObjs = $(this.MOD_CALCULATOR_MAIN_DIV).getElementsByTagName("select");
   _yuiEvent.addListener(inputsArray, "change",  this.Calculate,  this,  true );
   _yuiEvent.addListener(selectObjs, "change",  this.Calculate,  this,  true );
   
   _yuiEvent.addListener("newSymRateInput", "change",  this.OnNewSymRateChange,  this,  true );
   _yuiEvent.addListener("newOccBandwidthInput", "change",  this.OnNewOccBwChange,  this,  true );
   if(this.inWebUi) { _yuiEvent.addListener(this.EXPORTBUTTONID, "click",  this.ExportToWebUI,  this,  true ); }
   };

      
/***********************************************************
 *   Displays calculator as a dragabble panel in the 
 *   current broser window.
 ************************************************************/
MOD_CALC.prototype.Show = function()
   {
   this.modCalcPanel.show();
   };

/*******************************************
 * This special case disables the reverseCal flag
 * before performing instant calculation
 ******************************************/
MOD_CALC.prototype.OnNewSymRateChange = function()
   {
   this.reverseCalc = false;
   this.Calculate();
   };
   
/*************************************************
 * This special case enables the reverseCalc flag
 * before performing instant calculation
 ************************************************/
MOD_CALC.prototype.OnNewOccBwChange = function()
   {
   this.reverseCalc = true;
   this.Calculate();
   };

   
/******************************************************************************************
 * Triggered after every change in the input fields of the calculator.
 * Updates all result values, and displays them in the Web Browser's panel.
******************************************************************************************/
MOD_CALC.prototype.Calculate = function()
    {
    
    var currBitRateWPilots, currBitRateNoPilots, currBitRatePilotsRecommended,
    bitRateWPilots, bitRateNoPilots, bitRatePilotsRecommended,
    currFormatNum, newFormatNum, currSymRate, currRolloff, newSymRate, newRolloff,
    currBitRate, currOccBw, newBitRate, newOccBw, symRateLinkMarginChng, fecLinkMarginChng, 
       rolloffLinkMarginChng, powerLinkMarginChng, totLinkMarginChng, totBitRateChng, percBitRateChng,
       inputObjs;
    this.ResetWarnings();
    inputObjs = $(this.MOD_CALCULATOR_MAIN_DIV).getElementsByTagName("input");

    for(var i=0; i<inputObjs.length; i++)
       {
       switch(inputObjs[i].type)
          {
          case "text":
             var fieldVal = parseInt(inputObjs[i].value, 10);
             if((fieldVal===undefined)||(fieldVal===null)||(isNaN(fieldVal))||(inputObjs[i].length<2))
                {
                if(!(
                   ((this.reverseCalc) && (inputObjs[i].id=="newOccBandwidthInput"))||
                   ((!this.reverseCalc) && (inputObjs[i].id=="newSymRateInput"))
                   )) //!< Skip warning in reverse calculation and empty newOccBw 
                   {
                   this.SetWarning("Invalid input value.  Check highlighted areas.", this.GetInputLabelId(inputObjs[i]));
                   }  
                break;
                }
             break;
          case "checkbox":
             break;
          default: //??  unknown input type
             break;
          }
       }

    currFormatNum = parseInt($("currModModeSelect").value, 10); 
    currSymRate = parseFloat($("currSymRateInput").value, 10);
    currRolloff = this.ROLLOFFVALARRAY[parseInt($("currRolloffSelect").value, 10)] ;
    
    newFormatNum = parseInt($("newModModeSelect").value, 10);
    newRolloff = this.ROLLOFFVALARRAY[parseInt($("newRolloffSelect").value, 10)] ;

    if(this.reverseCalc)
       {
       newOccBw = parseInt($("newOccBandwidthInput").value, 10);
       newSymRate = newOccBw / (1+(newRolloff/_HUNDRED)); 
       }
    else
       {
       newSymRate = parseFloat($("newSymRateInput").value, 10);
       newOccBw = newSymRate * (1+(newRolloff/_HUNDRED));
       }

    currBitRateNoPilots = currSymRate * this.MODFORMAT[currFormatNum].BITRATENP;
    currBitRateWPilots = currSymRate * this.MODFORMAT[currFormatNum].BITRATEWP;
    currBitRatePilotsRecommended = currSymRate * this.MODFORMAT[currFormatNum].BITRATERP;
    
    switch($("currUsePilotsSelect").value)
       {
       case "Y":
          currBitRate = currBitRateWPilots;
          break;
       case "N":
          currBitRate = currBitRateNoPilots;
          break;
       case "R":
          currBitRate = currBitRatePilotsRecommended;
          break;
       default:
          //TODO: handle error and exit
          return;
       }
    
    
    currOccBw = currSymRate * (1+(currRolloff/_HUNDRED));
    
    bitRateNoPilots = newSymRate * this.MODFORMAT[newFormatNum].BITRATENP;
    bitRateWPilots = newSymRate * this.MODFORMAT[newFormatNum].BITRATEWP;
    bitRatePilotsRecommended = newSymRate * this.MODFORMAT[newFormatNum].BITRATERP;

    switch($("newUsePilotsSelect").value)
       {
       case "Y":
          newBitRate = bitRateWPilots;
          break;
       case "N":
          newBitRate = bitRateNoPilots;
          break;
       case "R":
          newBitRate = bitRatePilotsRecommended;
          break;
       default:
          //TODO: handle error and exit
          return;
       }



    symRateLinkMarginChng = GetLogarithm10(newSymRate / currSymRate)*(-10);
    fecLinkMarginChng = this.MODFORMAT[currFormatNum].CSAT - this.MODFORMAT[newFormatNum].CSAT;

    //TODO: Encapsulate in separate function, and replace magic values..  something along the lines of (GetRolloffLinkMarginChange(...))
    if(currRolloff==35)
       {
       if(newRolloff==35)
          {
          rolloffLinkMarginChng = 0;
          }
       else
          {
          rolloffLinkMarginChng = -0.3;
          }
       }
    else if(currRolloff==25)
       {
       if(newRolloff==35)
          {
          rolloffLinkMarginChng = 0.3;
          }
       else
          {
          rolloffLinkMarginChng = 0;
          }
       }
    else
       {
       rolloffLinkMarginChng = 0;
       }

    //get powerLinkMarginChng
    if($("saturationSelect").value == "SINGLE")
       { //carrier is run at saturation
       powerLinkMarginChng = 0;
       }
    else
       {
       powerLinkMarginChng = 10 * GetLogarithm10(newSymRate / currSymRate);
       }

    totLinkMarginChng = symRateLinkMarginChng + fecLinkMarginChng + rolloffLinkMarginChng + powerLinkMarginChng;
   
    totBitRateChng =  newBitRate - currBitRate;
    percBitRateChng = totBitRateChng / currBitRate;

    
    //display in browser panel
    if(!isNaN(currBitRate)){  $("currBitRateSpan").innerHTML = currBitRate.toFixed(this.PRECISION);   }
    else{$("currBitRateSpan").innerHTML = "NaN";   }
    
    if(!isNaN(currOccBw)){  $("currOccBandwidthSpan").innerHTML = currOccBw.toFixed(this.PRECISION);   }
    else{$("currOccBandwidthSpan").innerHTML = "NaN";}

    if(!isNaN(newBitRate)){  $("newBitRateSpan").innerHTML = newBitRate.toFixed(this.PRECISION);   }
    else{$("newBitRateSpan").innerHTML = "NaN";}

    if(!isNaN(symRateLinkMarginChng)){  $("marginSymRateChange").innerHTML = symRateLinkMarginChng.toFixed(this.PRECISION);   }
    else{$("marginSymRateChange").innerHTML = "NaN";}

    if(!isNaN(fecLinkMarginChng)){  $("marginFecChange").innerHTML = fecLinkMarginChng.toFixed(this.PRECISION);   }
    else{$("marginFecChange").innerHTML = "NaN";}

    if(!isNaN(rolloffLinkMarginChng)){  $("marginRolloffChange").innerHTML = rolloffLinkMarginChng.toFixed(this.PRECISION);   }
    else{$("marginRolloffChange").innerHTML = "NaN";}

    if(!isNaN(powerLinkMarginChng)){  $("marginPowerChange").innerHTML = powerLinkMarginChng.toFixed(this.PRECISION);   }
    else{$("marginPowerChange").innerHTML = "NaN";}

    if(!isNaN(totLinkMarginChng)){  $("marginTotalChange").innerHTML = totLinkMarginChng.toFixed(this.PRECISION);   }
    else{$("marginTotalChange").innerHTML = "NaN";}
    
    if(!isNaN(percBitRateChng)){  $("percentageBitRateChange").innerHTML = (percBitRateChng*_HUNDRED).toFixed(this.PRECISION) + "%";   }
    else{$("percentageBitRateChange").innerHTML = "NaN%";}
    
    if(this.reverseCalc)
       {
       if(!isNaN(newSymRate)){  $("newSymRateInput").innerHTML = newSymRate.toFixed(this.PRECISION);   }
       else{$("newSymRateInput").innerHTML = "NaN";}
       }
    else
       {
       if(!isNaN(newOccBw)){  $("newOccBandwidthInput").value = newOccBw.toFixed(this.PRECISION);   }
       else{$("newOccBandwidthInput").value = "NaN";}
       }
        
    return;

    };

    
/******************************************************************************************
  * Imports Current Settings from an external source.  
  * Usually, the Modulator Tab in the ADTEC Myles Project
 ******************************************************************************************/
MOD_CALC.prototype.ImportCurrSettings = 
    function
    (
    currModType,
    currModMode,
    currSymbolRate,
    currRolloff,
    currUsePilots,  //int.  0: Pilots OFF..  1: Pilots ON.
    currSaturation //(Optional) Boolean.  TRUE: Use saturation.  FALSE: Do Not use saturation
    )
    {
    
    if((currSaturation!==undefined)&&(currSaturation!==null))
       {
       $("saturationSelect").value = (currSaturation)? "SINGLE":"MULTI";
       }
    else
       {
       $("saturationSelect").value = "SINGLE";
       currSaturation = false;
       }

    var currModFormat = this.GetModFormat(currModType, currModMode, currSaturation);
    
    $("currSymRateInput").value = currSymbolRate;
    $("currRolloffSelect").value =  currRolloff;
    
    if(parseInt(currModType, 10) != _LBM_DVBS2_VAL) 
       {
       $("currUsePilotsSelect").disabled = true;
       $("currUsePilotsSelect").value = "N"; //if DVB-S@ is not active, pilots are disabled, and default to NO pilots.
       }
    else
       {
       $("currUsePilotsSelect").value = (currUsePilots===0)? "N": "Y";
       }
    
    if(isNaN(currModFormat) || currModFormat <0)
       {
       this.SetWarning("Current Modulation Mode could not be determined. Please manually select it from the dropdown list.", this.GetInputLabelId( $("currModModeSelect")));
       }
    else
       {
       $("currModModeSelect").value = currModFormat; 
       this.Calculate();
       }
    };
  

 /******************************************************************************************
  * Maps the Newtec Modulation Type nModulation Format to the calculator's Modulation
  * Format that includes both under a single selection menu (dropdown).
  * 
  * TODO: replace magic values in this method.
 ******************************************************************************************/
MOD_CALC.prototype.GetModFormat = function
   (
   modType, //DVB-S / DVB-S2 
   modMode,
   currSaturation
   )
   {
   var result = -1;
   if(modType==_MODTYPE.DVB_S)
      {
      switch(parseInt(modMode, 10))
         {
         case 11: result = 1; break;// DVB-S QPSK (FEC 1/2)
         case 12: result = 2; break;//DVB-S QPSK (FEC 2/3)
         case 13: result = 3; break;//DVB-S QPSK (FEC 3/4)
         case 15: result = 4; break;//DVB-S QPSK (FEC 5/6)
         case 17: result = 5; break;//DVB-S QPSK (FEC 7/8)
         
         case 16: result = -1; break;//TODO:  Unsupported mod mode..  Not in Excel spreadsheet
            
         default: result = -1; break; //unknown or invalid mod mode
         }
      } //end DVB-S type
   else if(modType==_MODTYPE.DVB_S2)
      {
      
      switch(parseInt(modMode, 10))
         {
         case 13: result = 19; break; //QPSK_3/4
         case 21: result = 13; break; //QPSK_1/4
         case 22: result = 14; break; //QPSK_1/3
         case 23: result = 15; break; //QPSK_2/5
         case 24: result = 17; break; //QPSK_3/5
         case 25: result = 20; break; //QPSK_4/5
         case 26: result = 22; break; //QPSK_8/9
         case 27: result = 23; break; //QPSK_9/10
         
         case 81: result = 24; break; //8PSK_3/5
         case 82: result = 25; break; //8PSK_2/3
         case 83: result = 26; break; //8PSK_3/4
         case 85: result = 27; break; //8PSK_5/6
         case 88: result = 28; break; //8PSK_8/9
         case 89: result = 29; break; //8PSK_9/10
         
         case 63: result = 11; break; //16QAM_3/4
         case 67: result = 12; break; //16QAM_7/8
         
         case 42: //16APSK_2/3
            if(currSaturation){result = 36;}
            else{result = 30;}  
            break; 
            
         case 43: //QPSK (FEC 3/4)
            if(currSaturation){result = 37;}
            else{result = 31;}  
            break;
            
         case 44: //16APSK_4/5
            if(currSaturation){result = 38;}
            else{result = 32;}  
            break;
            
         case 45: //16APSK_5/6
            if(currSaturation){result = 39;}
            else{result = 33;}  
            break;
         
         case 48: //16APSK_8/9
            if(currSaturation){result = 40;}
            else{result = 34;}  
            break;
            
         case 49: //16APSK_9/10
            if(currSaturation){result = 41;}
            else{result = 35;}  
            break;
            
         case 53: //32APSK_3/4
            if(currSaturation){result = 47;}
            else{result = 42;}  
            break;
            
         case 54: //32APSK_4/5
            if(currSaturation){result = 48;}
            else{result = 43;}  
            break;
            
         case 55: //32APSK_5/6
            if(currSaturation){result = 49;}
            else{result = 44;}  
            break;
            
         case 58: //32APSK_8/9
            if(currSaturation){result = 50;}
            else{result = 45;}  
            break;
            
         case 59: //32APSK_9/10
            if(currSaturation){result = 51;}
            else{result = 46;}  
            break;
         
         default: result = -1; break; //unknown or invalid mod mode.
            
         }
      }

   return result;
   };

   

   /*****************************************************************************
* @file
* @author  Original:      German Escallon
* @author  Contributors:  
* @date    Created:       2011
* @date    Last Edit:     $Date$ by $Author$
* Description: This file handles the AJAX calls to the devices.
*****************************************************************************/ 
   
var 
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/ 
GetMylesXHRStr = function()
   {
   return _MYLESURL + "?req=" + Math.random();   
   },

/**************************************************
 * Searches for predefined error message prefix in requestHandler response.
 * and returns whether the AJAX request was successful or not.  
 *************************************************/   
IsAjaxSuccess = function
   (
   respTxt
   )
   {
   if(respTxt.search(_REQHANDLER_ERR_MSG_PREFIX)!=-1)
      {//handle ajax error
      return false; 
      }
   return true;
   },

/***************************************************************************
 * Initiates Ajax asynchronous request to myles.
 * This uses the "GET" method, which implies that it is NOT to be used to make changes,
 * but to read the status of different API commands.
 * @return:  The corresponding YUI connection object. <rarely used> 
 ***************************************************************************/
GetMyles = function(callback, request, formItem, autoCursor)
   {
   if (formItem !== undefined && (formItem === true || formItem === false))
      {
      autoCursor = formItem;
      formItem = null;
      }
   else if (autoCursor === undefined)
      {
      autoCursor = true;
      }
   if (formItem === undefined)
      {
      formItem = null;
      }
   var requestUrl = GetMylesXHRStr() + request, successFn = callback.success;
   //  session management, logging, and other checks can be implemented here.
   callback.customevents =
      {
      onStart: function(type, args)
         {
         if(autoCursor){SetCursorWait();}
         },
      onComplete: function(type, args)
         {
         if(autoCursor){ResetCursor();}
         }
      };
   if (formItem !== null && $(formItem) !== undefined)
      {
      callback.success = function(o)
         {
         _yuiEvent.onAvailable(formItem, successFn, o);
         };
      }
   //session management, logging, and other checks can be implemented here.
   return _yuiConnect.asyncRequest("GET", requestUrl, callback, null);
   },

/***************************************************************************
 * Initiates Ajax asynchronous request to myles.
 * This uses the "POST" method, which implies that it is to be used only to make changes,
 * and not to check the status of different API commands.
 * @return:  The corresponding YUI connection object. <rarely used> 
 ***************************************************************************/
SetMyles = function
   (
   callback, //!< Callback object containing response handlers
   postData, //!< data to be submitted to the server
   autoCursor,  //!< Boolean (optional). If set to FALSE, cursor will not be affected. TRUE is default
   save, //!< Boolean (optional). If set to FALSE, settings will not be saved automatically. TRUE is default.
   refreshFn //!< function call (optional). Sends the page refresh function to the save function.
   )
   {
   //  session management, logging, and other checks can be implemented here.
   
   if(autoCursor===undefined ){  autoCursor  = true;  } //set default arg value
   if(save===undefined )      {  save        = true;  } //set default arg value 
   
   callback.customevents =
      {
      onStart: function(type, args)
         {
         if(autoCursor){SetCursorWait();}
         },
      onComplete: function(type, args)
         {
         if(autoCursor){ ResetCursor();}
         if(save){SaveSettings(refreshFn);}
         else if (
            (refreshFn !== undefined)  && //arg has been defined   
            (refreshFn !== null) &&       //arg is not null
            (typeof(refreshFn)=="function")
            )//arg is a function
            {
            if(refreshFn===TestConnection){setTimeout(TestConnection, 10000);}
            else
               {
               refreshFn(); //invoke function that refreshes the current tab
               }
            }
         }
      };
   return _yuiConnect.asyncRequest("POST", _MYLESURL, callback, postData);
   },
   
/***************************************************************************
 * Wrapper around the YUI AsyncRequest method exclusively for AJAX 
 * requests to ADTEC's requestHandler.
 * @return:  The corresponding YUI connection object. <rarely used>  
 ***************************************************************************/
ConnectToReqHandler = function
   (
   callback, //!< Callback object containing response handlers
   postData, //!< data to be submitted to the server. It is expected in the form:  "&q=<CMDH>+<CMD>+[PARAMS][&q=<CMDH>+<CMD>+[PARAMS]...]"
   autoCursor  //!< Boolean (optional). If set to FALSE, cursor will not be affected
   )
   {
   if(autoCursor===undefined ){autoCursor = true;} //set default value

   //session management, logging, and other checks can be implemented here.
   callback.customevents =
      {
      onStart: function(type, args)
         {
         if(autoCursor){SetCursorWait();}
         },
      onComplete: function(type, args)
         {
         if(autoCursor){ResetCursor();}
         }
      };
   return _yuiConnect.asyncRequest("POST", _REQHANDLER, callback, postData);
   },
   
/***************************************************************************
 * Wrapper around the YUI AsyncRequest method exclusively for AJAX 
 * requests to ADTEC's EIT Scheduler.
 * @return:  The corresponding YUI connection object. <rarely used>  
 ***************************************************************************/
ConnectToEitScheduler = function
   (
   callback, //!< Callback object containing response handlers
   postData //!< data to be submitted to the server. It is expected in the form:  "&q=<CMDH>+<CMD>+[PARAMS][&q=<CMDH>+<CMD>+[PARAMS]...]"
   )
   {
   //session management, logging, and other checks can be implemented here.
   return _yuiConnect.asyncRequest("POST", _REQHANDLER, callback, postData);
   },

/*********************************************************************************
*  uses CF SAVE API command to save current configuration settings
*********************************************************************************/
SaveSettings = function
   (
   pageToRefresh //!< Function to be called after settings have been saved.  Usually the function that refreshes the current tab.
   )
   {
   var XHRcallback = 
      {
      success: function(o)
         {
         var fnRegex = /^function$/i; //i makes it case insensitive
         if (
            (pageToRefresh !== undefined)  && //arg has been defined   
            (pageToRefresh !== null) &&       //arg is not null
            fnRegex.test(typeof(pageToRefresh))
            )//arg is a function
            {
            pageToRefresh(); //invoke function that refreshes the current tab
            }
         }, 
      failure: function(o)
         {
         LogMyles("ERROR: Settings could not be saved");
         }
      };
   var query = '';
   
   switch(GetProductId())
      {
      case _PRODUCT.SIGNEDJE.id:
      case _PRODUCT.EDJE4111.id:
      case _PRODUCT.SOLOIST411_HW2.id:
      case _PRODUCT.SOLOISTHDPRO.id:
      case _PRODUCT.RD60.id:
         query+= "DCMD CF SAVE" + _NEWLINE;
         break;
      
      case _PRODUCT.MEDIAHUBHD.id:
         query+= "ECMD CF SAVE" + _NEWLINE;
         if(setting["sysd_fea_mhstudio"]) //< Decoder settings are only supported for units that have the studio feature enabled.
            {
            query+= "DCMD CF SAVE" + _NEWLINE;
            }
         break;
         
      case _PRODUCT.MEDIAHUBHD_422.id:
         query+= ""
            +  "DCMD CF SAVE" + _NEWLINE 
            +  "ECMD CF SAVE" + _NEWLINE
            ;
         break;
      case _PRODUCT.EDJE5110.id:
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
         query+= "ECMD CF SAVE" + _NEWLINE;
         break;
         
      case _PRODUCT.HDMI2QAM.id:
      case _PRODUCT.YUV2QAM.id:
      case _PRODUCT.EN20.id:
      case _PRODUCT.EN10.id:
         query += ""
            +  "ECMD0 CF SAVE" + _NEWLINE
            +  "ECMD1 CF SAVE" + _NEWLINE
            ;
         break;
      
      case _PRODUCT.UNKNOWN.id:
      case _PRODUCT.DISPLAYMATE.id:
      case _PRODUCT.SOLOIST411_HW1.id:
      case _PRODUCT.ADCODE.id:
      case _PRODUCT.MEDIAHUB.id:
      case _PRODUCT.DTA.id:
      case _PRODUCT.DPI.id:
         break;
      default:
         break;   
      }
   SetMyles(XHRcallback, query, false, false);
   },  
   

/******************************************************************
* Loads the version number, which is to be displayed  at the top 
* left corner of the page..  right below the product logo
********************************************************************/   
LoadVersionNumber = function()
   {
   var XHRcallback =  //this object defines the callback for the XH request
      { 
      success: function(o)
         {
         if(ParseResponse(o)&&(setting["sysd_banner_version"]!==undefined))
            {
            $("versionDiv").innerHTML = "Version " + setting["sysd_banner_version"];//display
            }
         else
            {
            LogMyles("Version Load parse error. Retrying");
//               LoadVersionNumber();
            }
         },
      
      failure: function(o) 
         {
         LogMyles("AJAX Connection failed. Version could not be retrieved. Retrying");
         setTimeout(LoadVersionNumber, 2000);
         } 
      };
   var q= "&q=SYSD+BANNER";
   GetMyles(XHRcallback, q);
      
   }, 
   
/****************************************************************
* Stops the encoding/decoding processes.
******************************************************************/   
StopDevice = function()
   {
   
   var url = ' DCMD STOP' + _NEWLINE;
   
   if((GetProductId()==_PRODUCT.MEDIAHUBHD.id)     ||
      (GetProductId()==_PRODUCT.MEDIAHUBHD_422.id) ||
      (GetProductId()==_PRODUCT.EDJE5110.id))
      {
      url += 'ECMD STOP' + _NEWLINE;
      }
   
   var successHandler = function(o)
      {
      LogMyles("Device Stopped");
      };
   
   var failureHandler = function(o)
      {
      LogMyles("Ajax Error.  Device could not be stopped " + o.status + _TIME_DELIM + o.responseText);
      };
     
   //define callback object
   var XHRCallback =
      {
      success: successHandler, 
      failure: failureHandler
      };
   
   SetMyles(XHRCallback, url);
   },


/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/    
RenderUploadPanel = function()
   {
   //var effectObj = {};
   var panelConfig =  //set panel config properties
      {
      width:"500px",            
      iframe: false,
      autofillheight: "body", 
      fixedcenter: true, 
      constraintoviewport: true, 
      underlay:"matte",
      modal: false, 
      close:true, 
      visible:false, 
      draggable:true,
  //    effect: effectOBJ,
      xy: [0, 0]
      
      };
   
   _uploadPanel = new YAHOO.widget.Panel("uploadPanel", panelConfig); //create uploadPanel
   _uploadPanel.setHeader("Adtec Digital Uploader");
   
   var XHRCallback =
      {
      success: function(o)
         {
         _uploadPanel.setBody(o.responseText); //write ftp upload applet
         _uploadPanel.render();//render
        },
         
      failure: function(o)
         {
         LogMyles("FTP Upload could not be instantiated");
         }
      };
   
   
   var postdataObj = 
      {
      id: _REQID.GETFTPMARKUP, 
      req:Math.random()
      }; //build post arguments object
   var postdataStr = _yuiStringify(postdataObj); //transform object to string 
   ConnectToReqHandler(XHRCallback, postdataStr);
         
   },

/*********************************************************
*  Gets data from the server (in JSON format) and preloads 
*  the page with data that will populate the help menus of
*  the application 
*********************************************************/
LoadHelpMenus = function()
   {
   
   var XHRSuccess = function(o) //handler when request succeeds
      {
      var response = o.responseText;
      if(response.search(_REQHANDLER_ERR_MSG_PREFIX)!=-1)
         {//catch error
         LogMyles("HELP menus not retrieved. Verify syntax.");
         return; //exit function, preventing run-time error
         }
      
      //parse server responsed and transform into an array of JSON objects   
      _blurbObjs = _yuiParseJson(response);
      }; 
   
   var XHRCallback =
      {
      success: XHRSuccess,
      failure:function(o)
         {
         LogMyles("Help menus could not be loaded");          
         }
      }; 
  
      var postdataObj = 
         { 
         id: _REQID.GETINFOBLURBS,
         req:  Math.random() 
         }; //build post arguments objects
   var postdataStr = _yuiStringify(postdataObj); //transform object to string 
   ConnectToReqHandler(XHRCallback, postdataStr);
   },

   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetTunerID = function()
   {
   var query = ''
      +  '&q=DCMC+STS+0'
      +  '&q=DCMC+STS+1'   
      ;
   
      
   var XHRSuccess = function(o)
      {
      if(ParseResponse(o))
         {
         }
      else
         {
         LogMyles("ERROR: Tuner Id could not be found"); 
         }
      };
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("ERROR: Features not retrieved");
         }
      };
   GetMyles(XHRCallback, query);
         
   }, 
   
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/
UpdateProgramNumber = function()
   {
   var query = ''
      +  '&q=DCMD+DPN'
      +  '&q=DCMD+DPN+ACTIVE'
      ;
   var XHRSuccess = function(o)
      {
      if(ParseResponse(o))
         {
         if(   (setting["dcmd_dpn_isActive"] ) ) 
            { 
            switch(GetProductId())
               {
               
               case _PRODUCT.SOLOISTHDPRO.id:
                  if(($("mmoSelect").value=="RECEIVE") 
                     || ($("dvbSelect").value=="RECEIVE")) 
                     {
                     CreateProgramNumberOptions();
                     $("programNumberSelect").disabled = false; //enable program number select field   //TODO: remove magic numbers
                     $("progNumberLabel").style.color = _ADTCOLOR.DEFAULT; //Restore program label  
                     }
                  else
                     { //type is OFF
                     $("programNumberSelect").disabled = true; //disable program number select field   //TODO: remove magic numbers
                     $("progNumberLabel").style.color = _ADTCOLOR.GREY; //Grey out program label 
                     DomSelectReset($("programNumberSelect"));
                     }
                  break;
               
               case _PRODUCT.SOLOIST411_HW2.id:
                  if($("mmoSelect").value=="RECEIVE") 
                     {
                     CreateProgramNumberOptions();
                     $("programNumberSelect").disabled = false; //enable program number select field
                     $("progNumberLabel").style.color = _ADTCOLOR.DEFAULT; //Restore program label  
                     }
                  else
                     { //type is OFF
                     $("programNumberSelect").disabled = true; //disable program number select field
                     $("progNumberLabel").style.color = _ADTCOLOR.GREY; //Grey out program label   
                     DomSelectReset($("programNumberSelect"));
                     
                     }
                  break;
               
               case _PRODUCT.MEDIAHUBHD.id:
               case _PRODUCT.MEDIAHUBHD_422.id:
                  CreateProgramNumberOptions();
                  break;
               
               }//end switch
            }
         else
            {
            if((GetProductId()==_PRODUCT.MEDIAHUBHD_422.id) || (GetProductId()==_PRODUCT.MEDIAHUBHD.id) || (GetProductId()==_PRODUCT.SOLOISTHDPRO.id)) 
               {
               //no programs available 
               $("programNumberSelect").disabled = true; //disable program number select field  
               $("progNumberLabel").style.color = _ADTCOLOR.GREY; //Grey out program label   
               DomSelectReset($("programNumberSelect"));  
               }
            }     
         }
      else
         {
         LogMyles("DPN Parse Error");   
         }
       
         
      };
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(obj)
         {
         LogMyles("DPN error");
         }  
      };
   
   GetMyles(XHRCallback, query);
   
   }, //end function UpdateProgramNumber   

   
/***************************************************************
 * Requests myles for the system log, and renders its contents
 * inside the LOG panel (non-hidden by default).  Once contents are 
 * ready to be displayed, the panel is shown.
 * 
 ***************************************************************/
ShowLogPanel = function()
   {
   ResetLog();
   var query =  '&LOG=ALL'   ;
   
   var XHRSuccess = function(o)
      {
      var logContents = (o.responseText).replace(/\n/g, "<br />"); //replaces newline chars for HTML representation       
      //sets panel configurations
      var logPnlConf = 
         {
         width: "900px",
         autofillheight: "body", 
         height: "500px",
         fixedcenter: true, 
         //constraintoviewport: true, 
         underlay:"matte",
         modal: false, 
         close:true,     
         visible:true,  //hidden by default
         draggable:true 
         };
      //creates panel object
      var elCntnr = document.createElement("div");
      elCntnr.id = _LOGPNLDIV;
      document.body.appendChild(elCntnr);
      
      var logPanel = new YAHOO.widget.Panel(_LOGPNLDIV, logPnlConf);
      logPanel.hideEvent.subscribe(function()
            {
            this.destroy(); //destroy html container.
            });
      //sets panel header
      logPanel.setHeader("<b>Adtec Digital Log</b>");
      logPanel.setBody('<p>' + logContents + '</p>');
      logPanel.render();
      };
   
   var XHRCllbck = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX Error. Log not retrieved");
         }
      }; 
   GetMyles(XHRCllbck, query);
   
   },
   
/*********************************************************
 *  Clears VBH History record
 *********************************************************/
ClearVBHistory = function(callbackFn, cmdh)
   {
   if(!cmdh){cmdh = 'ECMD';} //default is ECMD.
   var postData = cmdh + ' VBH 1' + _NEWLINE ;
   var XHRSuccess = function(o)
      {
      };
   var XHRcallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("Unable to clear VBI history.");
         ResetCursor();
         }
      }; 
   SetMyles(XHRcallback, postData, false, false, callbackFn);
   
   }, 


/********************************************************
 * Event handler when user clicks on the button 
 * to load a mod/demod profile.  First, verifies that the current 
 * selection is valid, then submits the AJAX request to the 
 * unit.
 *********************************************************/
LoadProfileCfg = function()
   {
   if(this.value == _DEFAULT_PROFILE_VAL)
      {
      alert("Invalid Profile Selected.");
      return;
      }
   var prfFilePath, saveLbm = false;
   prfFilePath = this.value;
   var postStr = 'SYSD PROFILE RUN \"' + prfFilePath + '\"' + _NEWLINE;
  _saf0Changed = _saf1Changed = true;
   
   var XHRCallback = 
      {
      success: function(o)
         {
         SetInfoMessage("Succesfully Loaded Profile " + GetFileBasename(prfFilePath), 3000,_ADTCOLOR.GREEN);
         setTimeout(RenderDemod, 2000); //wait before reloading values. IE is experiencing problems.
         SetCursorWait(2200);
         SaveDemodSettings();
         },
      failure: function(o)
         {
         LogMyles("Failure loading Profile.");
         }
      };
   SetMyles(XHRCallback, postStr, false, true);
      
   },

/********************************************************
 * Event handler for save demod profile event. First, 
 * prompts the user for a profile name, then verifies that 
 * the user selction is valid, and finally submits the AJAX 
 * request to the unit.
 *********************************************************/
SaveProfile = function()
   {
   var nameRegex = /^[\w]{3,}$/i,
   demodKeyword, 
   prfName, postStr;
   demodKeyword = (HasNewtecDemod())? "ntcDevsMod01":( (HasAdtecDemod())? "adtecDemod": "");
   prfName = prompt("Please enter a profile name:");
   if(prfName===null)
      {//exit. User canceled the operation
      return;
      }
   if(!nameRegex.test(prfName))
      {//error.  user entered an invalid profile name
      alert("Invalid profile name. Only alphanumeric characters are allowed.");
      return;
      }
   
   postStr = "SYSD PROFILE SAVE " + demodKeyword + " \"" + prfName + "\"" + _NEWLINE;
   
   var XHRCallback = 
      {
      success: function(o)
         {
         if((o.responseText).search(/ERROR\-Bad Filename/i)==-1)
            {
            SetInfoMessage("Succesfully Saved Profile " + prfName, 3000,_ADTCOLOR.GREEN);
            }
         else
            {//error detected.
            alert("ERROR: \"" + prfName + "\" is not a valid profile name.");
            return;
            }
         },
      failure: function(o)
         {
         LogMyles("Failure saving profile." + prfName);
         }
      };
   
   SetMyles(XHRCallback, postStr, true, true, RefreshProfileList);
      
   },
  
/********************************************************
 * Event handler when user clicks on the button 
 * to delete a profile.  First, asks for user confirmation,
 * then verifies that the current selection is valid, 
 * and finally submits the AJAX request to the unit.
 *********************************************************/
DeleteProfile = function()
   {
   
   var pd = "SYSD PROFILE DELETE \"" + this.value + "\"" + _NEWLINE;
   if(this.value==_DEFAULT_PROFILE_VAL) 
      {
      alert("Invalid Profile Selected.");
      return;
      }  
   if(!confirm("Delete profile" + GetFileBasename(this.value))){   return;     } //request user confirmation
   var XHRCallback = 
      {  
      success: function(o)
         {
         SetInfoMessage("Succesfully Deleted Profile " + GetFileBasename(this.value), 3000,_ADTCOLOR.GREEN);
         setTimeout(RefreshProfileList, 2000); //wait 2 seconds for list to be updated
         },

      failure: function(o)
         {
         LogMyles("Error Deleting Profile.");
         }
      };
   
   var postdataObj = 
      {
      id: _REQID.DELETEFILE, 
      filepath: this.value
      };
   
   SetMyles(XHRCallback, pd, true, true, RefreshProfileList);
   },
   
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/
RenameProfile = function()
   {
   var val = this.value;
   if(val==_DEFAULT_PROFILE_VAL) 
      {
      alert("Invalid Profile Selected.");
      return;
      }
   var newPrfName = prompt("Please enter new profile name");
   
   if(newPrfName===null)
      {//operation cancelled 
      return;
      }
   
   if(this.id=="demodPrfManageSelect")
      {//tuner profile
      if(newPrfName.search(_TUNER_PROFILE_PREFIX)!==0)
         {//invalid prefix found.  Add prefix.
         newPrfName = _TUNER_PROFILE_PREFIX + newPrfName;
         }
      
      if(newPrfName.search(/.DVC$/)== -1) //search for proper extension
         {//invalid extension found..  add valid extension
         newPrfName = newPrfName + ".DVC";
         }
      
      var postData = "SYSD RENAME " + _TUNER_PROFILE_PREFIX + val + " " + newPrfName + _NEWLINE;
      
      var callback = 
         {
         success: function(o)
            {
            SetInfoMessage("Profile \"" + val + "\" successfully renamed as " + _DVC_PATH + "/" + newPrfName, _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
            },
         failure: function(o)
            {
            SetInfoMessage("AJAX error when Renaming Profile.  More information may be available in the System logs.", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.RED);
            LogMyles("AJAX error when Renaming Profile. More information may be available in the System logs.");
            }
         };
      SetMyles(callback, postData, true, true, RenderDemod);  
      
      }
   
   },

/********************************************************
 * Event handler for download profile event. First, 
 * verifies that the currently selected profile is valid,
 * and then proceeds to download it from the server.
 *********************************************************/
DownloadProfileCfg = function()
   {
   var DVCPATH = '/media/hd0/dvc/';
   if(this.value==_DEFAULT_PROFILE_VAL) 
      {
      alert("Invalid Profile Selected.");
      return;
      }  
   else
      {
      window.location.href = "/download?file=" + DVCPATH+"prf" + this.value + ".DVC"; 
      }
   
   },


/******************************************************
* Tests whether the server can handle requests
* at the moment. Used when the firmware is updated, and
* the server is rebooting, or when unit is being reset.
********************************************************/
TestConnection = function()
   {
   var RECONNECT_INTERVAL = 10000;
   var successReconnectionHandler = function(o)
      {
      if(_rebootingStarted)
         {
         if(o.status==_XHR_OK_STATUSCODE)
            {
            SetInfoMessage('Server Ready.  Redirecting...') ;
            window.location = "/index.html"; //redirecting
            }
         else
            {
            SetInfoMessage('Status is ' + status) ;
            }
         }
      else
         {
         TestConnection();
         }
      };   
   
   var failedReconnectionHandler = function(o)
      { //connection failed. server is not ready
      _rebootingStarted = true; //computer is rebooting
      SetInfoMessage("Server is not ready. Attempting to reconnect in " + (RECONNECT_INTERVAL/_MILISECONDSPERSECOND) + " seconds ...") ;//interact w/ user
      setTimeout(TestConnection, RECONNECT_INTERVAL); //re-attempt request in a few seconds
      };
   
   //define callback object
   var XHRCallback =
      {
      success: successReconnectionHandler, 
      failure: failedReconnectionHandler,
      timeout: 3000 //stop if response is not received within 3 secs
      };

   SetInfoMessage("Attempting server connection..."); //interact w/ user
   _yuiConnect.asyncRequest("GET", "/index.html", XHRCallback, null);
       
   },
   
 
 /******************************************************************************
 * Saves the SYSD CFG settings.
 *******************************************************************************/
SaveSysd = function()
   {
   var q= 'SYSD CFG SAVE';
   var cb = {success:function(o){}, failure:function(o){}};
   SetMyles(cb, q, false, false);
   },

/********************************************************
 * Dynamically load/refreshes the dropdown 
 * options containing the available profiles. 
 *********************************************************/
RefreshProfileList = function
   (
   )
   {
   var q = '&q=SYSD+PROFILE+STATUS' + _NEWLINE;
   var callback = 
      {
      success: function(o)
         {
         var result = ParseLocally(o.responseText);
         
         if((result.sysd_profile.status).toUpperCase()=="READY")
            {
            LoadDemodProfileList($("demodPrfManageSelect"));
            }
         else
            {
            setTimeout(RefreshProfileList, _PRF_STATUS_CHECK_INTERVAL); //loop until ready
            }
         
         }, 
      failure: function(o)
         {
         LogMyles("RefreshProfileList(). Ajax error");
         }
      };
   
   GetMyles(callback, q);
   },
   
/**************************************************************
 * Updates the VBI History Table w/ the most current values.
 *************************************************************/
RefreshVBH = function(tableId, cmdh)
   {
   cmdh = cmdh.toLowerCase();
   if(!tableId){tableId = _STR_VBHTABID;} //Set default arg
   if(!cmdh){cmdh = "ecmd";} //Set default arg
   var query = "&q=" + cmdh.toUpperCase() + "+VBH";
   var callback = 
      {
      success: function(o)
         {
         setting[cmdh + "_vbh"] = null;
         if(ParseResponse(o))
            { 
            
            var ds =  new YAHOO.util.DataSource(setting[cmdh + "_vbh"]);
            ds.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
            ds.responseSchema = {fields: ['line', 'fid', 'count', 'len', 'sdid']}; 
            var cd = [
               {
               key:"line",
               label:'<b>Line</b>', 
               sortable:false,
               selected:false,
               formatter:function(elCell, oRecord, oColumn, oData)
                  {
                  elCell.innerHTML = oData;
                  }
               },          
               {
               key:"fid",
               label:'<b>Field ID</b>', 
               sortable:false,
               selected:false,
               formatter:function(elCell, oRecord, oColumn, oData)
                  {
                  elCell.innerHTML = oData;
                  }
               },
               {
               key:"count",
               label:'<b>Count</b>', 
               sortable:false,
               selected:false,
               formatter:function(elCell, oRecord, oColumn, oData)
                  {
                  elCell.innerHTML = oData;
                  }
               },
               {
               key:"len",
               label:'<b>Length</b>', 
               sortable:false,
               selected:false,
               formatter:function(elCell, oRecord, oColumn, oData)
                  {
                  elCell.innerHTML = oData;
                  }
               },
               {
               key:"sdid",
               label:'<b>DID/SDID</b>', 
               sortable:false,
               selected:false,
               formatter:function(elCell, oRecord, oColumn, oData)
                  {
                  elCell.innerHTML = oData;
                  }
               }
             ];
            var dt = new YAHOO.widget.DataTable(tableId, cd, 
                     ds, null);

            
            }
         else
            {
            LogMyles("Parse error when refreshing VBI History.");
            }
         },
         
      failure: function(o)
         {
         LogMyles("AJAX error when refreshing VBI History.");
         } 
      };

   GetMyles(callback, query);
   }
   ;

/*****************************************************************************
* @file
* @author Original: German Escallon
* @author Contributors: Michael Turner
* @date Created: 2010/06/29
* @date Last Edit: $Date$ by $Author$
* Description: Display utilities for MyLES.
******************************************************************************/

var

/*************************************************************************
 * Invokes product-specific html code to display the status panel
 **************************************************************************/
DisplayStatusPanel = function()
   {
   if(HasValidProductKey())
      {
      switch(GetProductId())
         {
         case _PRODUCT.DTA.id:  // dta
            $("statusPanel").innerHTML = GetStatusPanelHTMLDTA();
            GetVisualUpdatesDTA();
            break;
         
         case _PRODUCT.DPI.id: // dpi       
            $("statusPanel").innerHTML = GetStatusPanelHTMLDPI();
            GetVisualUpdatesDPI();
            break;
            
         case _PRODUCT.MEDIAHUBHD.id:     //mediahub-hd
         case _PRODUCT.MEDIAHUBHD_422.id: //mHUB_HD422
         case _PRODUCT.EDJE5110.id:       //edje-5110  
            $("statusPanel").innerHTML = GetStatusPanelHTMLLegEn();
            GetVisualUpdatesLegEn();
            break;
            
         case _PRODUCT.EN40.id:       //EN-40         
         case _PRODUCT.EN80.id:       //EN-80     
         case _PRODUCT.EN41.id:
         case _PRODUCT.EN81.id:
         case _PRODUCT.EN91.id:
            $("statusPanel").innerHTML = GetStatusPanelHTMLEncoders();
            GetVisualUpdatesEncoders();
            break;   
            
         case _PRODUCT.SIGNEDJE.id: //signEdje
         case _PRODUCT.EDJE4111.id: //edje-411
         case _PRODUCT.SOLOIST411_HW2.id: //soloist-4111_hw2     
         case _PRODUCT.SOLOISTHDPRO.id: // SoloistHD_Pro
            $("statusPanel").innerHTML = GetStatusPanelHTMLPlayers();
            GetVisualUpdatesPlayers();
            break;
         
         case _PRODUCT.HDMI2QAM.id:       //hdmi2qam
         case _PRODUCT.YUV2QAM.id:        //yuv2qam
         case _PRODUCT.EN20.id:           //EN20
         case _PRODUCT.EN10.id:           //EN10
            $("statusPanel").innerHTML = GetStatusPanelHTMLQuam();
            GetVisualUpdatesQuam();
         break;
         
         case _PRODUCT.RD60.id:       //rd-60
            $("statusPanel").innerHTML = GetStatusPanelHTMLTuners();
            GetVisualUpdatesTuners();
         break;
         }
      }
   else
      {
      $("statusPanel").innerHTML = 
         [
         GetStatusPanelStdHeader(),
         '<div style="color:FF0000"><h3>',
         'The product key is not active for this device. Please visit the <a href="#page=pg_fea">Features Page</a> for more info',
         '</h3></div>'
         ].join('');
      
      }
   }, 

/*************************************************************************
 * Invokes product-specific handler to display the status panel
 **************************************************************************/
UpdateStatusPanel = function()
   {
   if (_refreshStatusPanel)
      {
      switch(GetProductId())
         {
         case _PRODUCT.DTA.id: 
            UpdateStatus_DTA();
            break;
         
         case _PRODUCT.DPI.id: // dpi
            UpdateStatus_DPI();
            break;
         
         case _PRODUCT.MEDIAHUBHD.id:     //mediahub-hd
         case _PRODUCT.MEDIAHUBHD_422.id: //mHUB-HD422
         case _PRODUCT.EDJE5110.id:       //edje-5110
            UpdateStatus_Encoders();
            break;
         
         case _PRODUCT.EN40.id:  
         case _PRODUCT.EN80.id:
         case _PRODUCT.EN41.id:
         case _PRODUCT.EN81.id:
         case _PRODUCT.EN91.id:
            UpdateStatus_G4Encoders();
            break;
         
         case _PRODUCT.HDMI2QAM.id:
         case _PRODUCT.YUV2QAM.id:
         case _PRODUCT.EN20.id:
         case _PRODUCT.EN10.id:
            UpdateStatus_HDMI2QAM();
            break;
         
         case _PRODUCT.SIGNEDJE.id://signEdje
         case _PRODUCT.EDJE4111.id: //edje-411
         case _PRODUCT.SOLOIST411_HW2.id: ///soloist-4111_hw2
         case _PRODUCT.SOLOISTHDPRO.id: //SoloistHD_Pro
            UpdateStatus_Players();
            break;
         
         case _PRODUCT.RD60.id:       //rd60
            UpdateStatus_Tuners();
            break;
         }
      }
   else
      {
      setTimeout(UpdateStatusPanel, 2000);
      }
   }, 
   
/*************************************************************************
 * Alternate two divisions between hidden and displayed such that both divisions
 * will be neither shown nor hidden simultaneously.
 * @param id
 * @param id2
 **************************************************************************/
ToggleStatusPanelSectionVisibility = function(id, id2) 
   {
   var thisDiv = document.getElementById(id);
   var thisDiv2 = document.getElementById(id2);
   
   if (thisDiv.style.display == '') 
      {
      thisDiv.style.display = 'none';
      thisDiv2.innerHTML =    '<img src="/images/show.gif"/>';
   
      } 
   else 
      {
      thisDiv.style.display = '';
      thisDiv2.innerHTML =    '<img src="/images/hide.gif"/>';
      }
   }, 
   
   
/*******************************************************************
 * Returns a reference to the tab identified by the given id.
 * Returns null if the given id does not match any of the defined tabs.
 ******************************************************************/
GetTabById = function(tabId)
   {
   var result = _TAB[_TABIDX[tabId]];
   if(result===undefined)
      {
      LogMyles("GetTabById: Invalid param (tab id) received."); 
      result = null;
      }
   return result;
   },
   
/*******************************************************************
 * Returns a reference to the page identified by the given id.
 * Returns null if the given id does not match any of the defined pages.
 ******************************************************************/
GetPageById = function(pageId)
   {
   var result = _PAGE[_PAGEIDX[pageId]];
   if(result===undefined)
      {
      LogMyles("GetPageById: Invalid param (page id) received.");
      result = null;
      }
   return result;
   },
   
                  
/*************************************************************************
 * Browser history manager functions
 *************************************************************************/
/**************************************************************************
 * Initializes the browser history manager.  Also, redirects the user to
 * the page specified by the current bookmark (if any), or to the default page
 * otherwise.
 ***************************************************************************/
InitHistoryMgr = function()
   {

   var bookmarkedState = YAHOO.util.History.getBookmarkedState(_PAGE_ID);
   
   var initPageMarkupId = null;
   switch(GetProductId())
      {
      case _PRODUCT.DPI.id: //dpi
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.ch0].id; //default page is "Channels"
         break;
      case _PRODUCT.DTA.id: //dta   
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.fmw].id; //default page is "Firmware"
         break;
      case _PRODUCT.HDMI2QAM.id: //hdmi2qam
      case _PRODUCT.YUV2QAM.id:  //yuv2qam
      case _PRODUCT.EN20.id:     //EN20
      case _PRODUCT.EN10.id:     //EN10
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.tss].id; //default page is "Services"
         break;
      case _PRODUCT.MEDIAHUBHD.id:     //mediahub-hd
      case _PRODUCT.EDJE5110.id:       //edje-5110
      case _PRODUCT.MEDIAHUBHD_422.id: //mHUB-HD422         
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.ast].id; //default page is "ASI Transport"
         break;

      case _PRODUCT.RD60.id: //rd60
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.rds].id; //default page is "RD Services"
          break;
      case _PRODUCT.SIGNEDJE.id: //signEdge
      case _PRODUCT.EDJE4111.id: //edje-411
      case _PRODUCT.SOLOIST411_HW2.id: ///soloist-4111_hw2
      case _PRODUCT.SOLOISTHDPRO.id: //SoloistHD_Pro
         initPageMarkupId = bookmarkedState || _PAGE_PREFIX + _PAGE[_PAGEIDX.inv].id;  //default page is "Inventory"
         break; 
      }
   
   YAHOO.util.History.register ( _PAGE_ID , initPageMarkupId , OnPageChange , null , false); 
   
   // Initialize the browser history management library.
   try 
      {
      YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe");
      } 
   catch (e) 
      {
      OnPageChange.apply({"initState": initPageMarkupId});
      }
   
   var onHistoryReady = function()
      {
      InitNavigation();
      YAHOO.util.History.navigate(_PAGE_ID, initPageMarkupId);
      OnPageChange.apply({"initState": initPageMarkupId});
      };
      
   YAHOO.util.History.onReady(onHistoryReady);
   },
   
   
/****************************************************************************************
 *  Adds event listeners to all the defined tabs and pages, to capture navigation changes.
 *  All tabs and page definitions  become links to their respective page. 
 ***************************************************************************************/
InitNavigation = function()
   {
   var i, elId, clickedEl, anchors;
   
   anchors = $(_MAIN_MENU_ID).getElementsByTagName("div"); //get all tab elements
   for (i = 0; i < anchors.length; i++) 
      {
      elId = TrimPageTabPrefix(anchors[i].id);
      clickedEl =  GetTabById(elId);
      _yuiEvent.addListener(anchors[i], "click", OnTabClick,  clickedEl, true);
      }

   anchors = $(_PAGE_ID).getElementsByTagName("div"); //get all page elements
   for (i = 0; i < anchors.length; i++) 
      {
      elId = TrimPageTabPrefix(anchors[i].id);
      clickedEl =  GetPageById(elId);
      _yuiEvent.addListener(anchors[i], "click", OnPageClick, clickedEl, true);
      }
   },

/*****************************************************************************************
 * Clicking on a tab, has the same effect as clicking on its first defined page.
 ****************************************************************************************/
OnTabClick = function()
   {
   OnPageClick.apply(_PAGE[this.subnav[0]]);
   },
   
/******************************************************************
 * Adds an entry to the browser history manager.  This action ultimately results
 * in redirecting the user to the specified page.
 *****************************************************************/
OnPageClick = function()
   {
   var navKey = _PAGE_PREFIX + this.id;
   YAHOO.util.History.navigate(_PAGE_ID, navKey); 
   },
   
   
/****************************************************************************
 * returns the tab corresponding to the given Page id for the specified product.
 * If no tab is matched, null is returned (very unlikely).
 ***************************************************************************/
GetTabByPageId = function(pageId)
   {
   var result = null;
   var i, j;
   for(i=0; (i<_product.tabs.length) && (result===null); i++)
      {
      for(j=0; j<_TAB[_product.tabs[i]].subnav.length; j++)
         {
         if(_PAGE[_TAB[_product.tabs[i]].subnav[j]].id == pageId)
            {
            result = _TAB[_product.tabs[i]];
            break;
            }
         }
      }
   return result;
   },
   

/****************************************************************************
 * Event handler when a change in the navigation has been detected.  
 * It will update the highlighting of the navigation tabs, re-draw the 
 * corresponding pages for the current selection, and load the newly selected
 * page.
 ***************************************************************************/
OnPageChange = function()
   {
   var 
      bkState = null, 
      bkPage = null,
      bkTab = null
      ;
   if(this.initState!==undefined)
      {//initial loading.
      bkState = this.initState;
      }
   else
      {
      bkState = YAHOO.util.History.getCurrentState(_PAGE_ID);
      if(bkState===null){ return;} //prevent error when pressing back button and bookmark state is not identified.  
      }
   bkPage = GetPageById(TrimPageTabPrefix(bkState)); //gets the bookmarked page
   bkTab = GetTabByPageId(bkPage.id); //gets the bookmarked tab
   SetTabChange(bkTab); //highlights the selected tab
   SetPagesForCurrentTab(); //re-draws the sub-navigation bar exposing only the pages required.
   SetPageChange(bkPage); //highlights the selected page
   
   switch(_currPage.id)
      {
      case _PAGE[_PAGEIDX.adc0].id:      case _PAGE[_PAGEIDX.adc1].id:      case _PAGE[_PAGEIDX.adc2].id:      case _PAGE[_PAGEIDX.adc3].id:
      case _PAGE[_PAGEIDX.adc4].id:      case _PAGE[_PAGEIDX.adc5].id:      case _PAGE[_PAGEIDX.adc6].id:      case _PAGE[_PAGEIDX.adc7].id://     
         _currPage.render.apply(_currPage, [GetAudioIdxFromPgId(_currPage.id) + 1]); //exception for audio pages..  the index of the requested page is needed for the rendering function.
         break; 
      case _PAGE[_PAGEIDX.ch0].id:      case _PAGE[_PAGEIDX.ch1].id:      case _PAGE[_PAGEIDX.ch2].id:      case _PAGE[_PAGEIDX.ch3].id:
      case _PAGE[_PAGEIDX.ch4].id:      case _PAGE[_PAGEIDX.ch5].id:      case _PAGE[_PAGEIDX.ch6].id:      case _PAGE[_PAGEIDX.ch7].id:
      case _PAGE[_PAGEIDX.ch8].id:      case _PAGE[_PAGEIDX.ch9].id:      case _PAGE[_PAGEIDX.ch10].id:     case _PAGE[_PAGEIDX.ch11].id:
         _currPage.render.apply(_currPage, [GetDpiChIdxFromPgId(_currPage.id)]); //exception for DPI Channel pages..  the index of the requested page is needed for the rendering function.
         break;
      case _PAGE[_PAGEIDX.qen0].id:     case _PAGE[_PAGEIDX.qen1].id:
         _currPage.render.apply(_currPage, [GetEncoderIdxFromPgId(_currPage.id)]);
         break;
      case _PAGE[_PAGEIDX.qvb0].id:     case _PAGE[_PAGEIDX.qvb1].id:
         _currPage.render.apply(_currPage, [GetVBIIdxFromPgId(_currPage.id)]);
         break;
      case _PAGEIDX.max:
         break;
      default:
         _currPage.render.apply(_currPage); //render the selected page
         break;
   
      }
   }, 
   
/************************************************************
 * Hides all the elements in the page bar. 
 *************************************************************/
ResetPageBar = function()
   {
   var els;
   els = $(_PAGE_ID).getElementsByTagName("div");
   for(var i=0; i<els.length; i++)
      {
      $(els[i].id).style.backgroundColor = GetProductColor();
      DomHideEl(els[i]);
      }
   }, 
   
/************************************************************
 * in order to distinguish the tabs and pages ids, from the actual thing
 * (and to prevent polluting the namespace), every tab/page reference has
 * a prefix, as interpreted by the browser.  This method remos that prefix,
 * returning the tab/page id referenced. 
 *************************************************************/
TrimPageTabPrefix = function(str)
   {
   var pgRegexStr = "^" + _PAGE_PREFIX ;
   var tabRegexStr = "^" + _TAB_PREFIX ;
   var pgRegex = new RegExp(pgRegexStr, "");
   var tabRegex = new RegExp(tabRegexStr, "");
   var ret = null;

   if(pgRegex.test(str))
      {//page prefix found at the beginning of the given string
      ret = str.substring(_PAGE_PREFIX.length); //removes prefix for page
      }
   else if(tabRegex.test(str))
      {
      ret = str.substring(_TAB_PREFIX.length); //removes prefix fvor tab
      }
   else
      {//highly unlikely
      LogMyles("TrimPageTabPrefix Error: The given string does not match a page or tab id."); 
      ret = str;   
      }
   return ret;
   },
   

   
/***************************************************************
 * Audio page ids come in the form adc_0, adc_1, adc_2, etc..
 * This function returns the index (0-_NUM_AUDIOS) for the given 
 * page id. In case of error, -1 is returned.
 ***************************************************************/
GetAudioIdxFromPgId = function(pageId)
   {
   var regex = /^adc(\d+)$/;
   var result = -1;
   if(regex.test(pageId))
      {
      result = parseInt(pageId.replace(regex, "$1"), 10);
      }
   else
      {
      LogMyles("GetAudioIdxFromPgId Error. The given argument is not a valid audio page id.");
      }
   return result;
   },
/***************************************************************
 * DPI Channel page ids come in the form adc_0, adc_1, adc_2, etc..
 * This function returns the index (0-_NUM_AUDIOS) for the given 
 * page id. In case of error, -1 is returned.
 ***************************************************************/
GetDpiChIdxFromPgId = function(pageId) 
   {
   var regex = /^ch(\d+)$/;
   var result = -1;
   if(regex.test(pageId))
      {
      result = parseInt(pageId.replace(regex, "$1"), 10);
      }
   else
      {
      LogMyles("GetAudioIdxFromPgId Error. The given argument is not a valid audio page id.");
      }
   return result;
   },
   
/*************************************************************************************************
 * Changes the color scheme in the navigation bar to highlight the given tab.  also, updates the
 * global reference to the current tab.  
 *************************************************************************************************/
SetTabChange = function( newTab)
   {
   if(_currTab!==null)
      {//prevent errors in initial call, when no tab has been previously selected
      $(_TAB_PREFIX + _currTab.id).style.backgroundColor = GetNavColor(); //reverse previous tab color to default.
      }
   $(_TAB_PREFIX + newTab.id).style.backgroundColor = GetProductColor();
   _currTab = newTab;
   },
   
/*************************************************************************************************
 * Displays only the pages corresponding to the current tab, hiding all others.
 *************************************************************************************************/
SetPagesForCurrentTab = function()
   {
   ResetPageBar();
   for(var i=0; i<_currTab.subnav.length; i++) //for each subnavigation element in current tab
      {
      DomShowEl($(_PAGE_PREFIX + _PAGE[_currTab.subnav[i]].id));
      }
   
   if(i<=1)  {  DomHideEl($(_PAGE_ID));   }//hides page bar when there is only one page per tab.
   else { DomShowEl($(_PAGE_ID)); }//shows all pages for the current tab, when there is more than one option available.
   },
   
/*************************************************************************************************
 * Changes the color scheme in the page bar to highlight the given page.  Also, updates the
 * global reference to the current page.   
 *************************************************************************************************/
SetPageChange = function(newPage)
   {
   
   if(_currPage!==null)
      {
      $(_PAGE_PREFIX + _currPage.id).style.backgroundColor = GetProductColor();
      }

   var pageKey = _PAGE_PREFIX + newPage.id;
   $(pageKey).style.backgroundColor = GetSubNavColor();
   _currPage = newPage;
   },
   
/***************************************************************
 * Qam encoder page ids come in the form qen0 and qen1
 * This function returns the index for the given 
 * page id. In case of error, -1 is returned.
 ***************************************************************/
GetEncoderIdxFromPgId = function(pageId)
   {
   var regex = /^qen(\d+)$/;
   var result = -1;
   if(regex.test(pageId))
      {
      result = parseInt(pageId.replace(regex, "$1"), 10);
      }
   else
      {
      LogMyles("GetEncoderIdxFromPgId Error. The given argument is not a valid encoder page id.");
      }
   return result;
   },
   
/***************************************************************
 * Qam vbi page ids come in the form qvb0 and qvb1
 * This function returns the index for the given 
 * page id. In case of error, -1 is returned.
    ***************************************************************/
GetVBIIdxFromPgId = function(pageId)
   {
   var regex = /^qvb(\d+)$/;
   var result = -1;
   if(regex.test(pageId))
      {
      result = parseInt(pageId.replace(regex, "$1"), 10);
      }
   else
      {
      LogMyles("GetVBIIdxFromPgId Error. The given argument is not a valid vbi page id.");
      }
   return result;
   }
   ;/*****************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file contains different functions and utilities that serve common purposes
 *              for the Web User interface
 *****************************************************************************/
 
var
   
/*********************************************************************************
* Resets LOG array avoid including repeated entries. 
*********************************************************************************/
ResetLog = function()
   {
   setting["log_err_date"] = [];
   setting["log_err_time"] = []; 
   setting["log_err_device"] = [];
   setting["log_err_process"] = []; 
   setting["log_err_msg"] = []; 
   _logIndex = 0;
   }, 
   
  
 
/***************************************************************************************************************
 * These functions are used to set/stop the recursive call for the status panel update.
 **************************************************************************************************************/
SetStatusUpdate = function()
   {
   
   _updateStatus = true;
   $("statusPanel").style.color = _ADTCOLOR.BLACK;
   _yuiEvent.onContentReady( "boxStatus",   function () 
      {                 
      $("boxStatus").innerHTML = "";
      UpdateStatusPanel();
      }
   );
  
   }, 
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/  
StopStatusUpdate = function()
   {  
   _updateStatus = false;
   $("statusPanel").style.color = _ADTCOLOR.GREY;
   $("boxStatus").style.color = _ADTCOLOR.RED;
   $("boxStatus").innerHTML = 'Updated: ' + GetCurrentTime();
   }, 

/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetUiState = function()
   {
   return _currUiState;
   },

SetUiState = function(uiState)
   {
   _currUiState = uiState;
   }, 

/*********************************************
* Re-directs user to index.html page.
* Authenticated session remains valid 
*********************************************/
Logout = function()
   {
   window.location = "/index.html";
   }, 
   
 
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
ShowUploader = function()
   {
   _uploadPanel.show();
   },
   
  
   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
RenderHelpPanel = function()
   {
   
   var panelConfig = 
   {
      width:'450px',
     // height: "300px",
      iframe: false,
      autofillheight: null, 
      fixedcenter: false, 
      constraintoviewport: true, 
      underlay:"matte",
      modal: false, 
      close:true, 
      visible:false, 
      draggable:true,
      
      
 //    effect: effectOBJ,
      xy: [0, 0]
   };
   
   _helpPanel = new YAHOO.widget.Panel("helpPanel", panelConfig); //create helpPanel
   _helpPanel.render();//render
    
   },

GetHelpDataById = function(helpId)
   {
   var result = null, found=false, i=0;
   if(_blurbObjs)
      {
      //try custom definitions first
      if(_blurbObjs.custom && (_blurbObjs.custom instanceof Array))
         {
         for(i=0; i<_blurbObjs.custom.length; i++)
            {
            if(_blurbObjs.custom[i].id && (_blurbObjs.custom[i].id==helpId))
               {
               result = _blurbObjs.custom[i];
               found = true;
               break;
               }
            }
         }
      
      if(!found)
         {
         //try main (general) help blurb definitions last
         if(_blurbObjs.main && (_blurbObjs.main instanceof Array))
            {
            for(i=0; i<_blurbObjs.main.length; i++)
               {
               if(_blurbObjs.main[i].id && (_blurbObjs.main[i].id==helpId))
                  {
                  result = _blurbObjs.main[i];
                  break;
                  }
               }
            }
         }
      }
  
   return result;
   },   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
ShowHelp = function
   (
   helpId,
   anchorObj
   )
   {
    
   var helpContainer = GetHelpContainer();
   var panelConfig = 
      {
      width:"450px",
      iframe: false,
      autofillheight: null, 
      fixedcenter: false, 
      constraintoviewport: true, 
      underlay:"matte",
      modal: false, 
      close:true, 
      visible:false, 
      draggable:true,
      xy: [0, 0]
      }; 
   
   if(_helpPanel!==null){ _helpPanel.destroy(); } //destroy previous help panel if it exists
   _helpPanel = new YAHOO.widget.Panel(helpContainer.id, panelConfig); //create helpPanel
   _helpPanel.render();//render help panel
   
   var helpData = GetHelpDataById(helpId);
   if(helpData===null)
      {
      _helpPanel.setHeader(_NA);
      _helpPanel.setBody("We apologize. Info is not available for this field.");   
      }
   else
      {
      _helpPanel.setHeader(helpData.header);
      _helpPanel.setBody(helpData.body);
      }
   
   
   
   
   //context aligns the rendered panel's bottom left corner with the calling object's top left corner
   //before showing the element, and when window is resized.
   var contextObj = 
      [
      anchorObj.id, //element to be aligned with
      "tl",  //align topleft of anchor
      "bl",  // with bottomleft of panel 
         [
         "beforeShow",//before showing
         "windowResize"
         ]
      ];
   
   _helpPanel.cfg.setProperty("context", contextObj); //set context 
   
   var resizeConfig = 
      {
      //handles: ['br'],
      autoRatio: false,
      minWidth: 200,
      minHeight: 100,
      status: true
      };
   
   if(_resizeHelp!==null){   _resizeHelp.destroy(); }
   _resizeHelp = new YAHOO.util.Resize("helpPanel", resizeConfig); //create resize object
   
   _helpPanel.show();//show panel
      
   },
   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/ 
GetHelpContainer = function()
   {
   var helpContainer = document.createElement("div");
   var body = document.createElement("div");
   var header = document.createElement("div");
   header.className = "hd";
   body.className = "bd";
   helpContainer.id = "helpPanel";
   helpContainer.appendChild(header);
   helpContainer.appendChild(body);
   ($("panelContainer")).appendChild(helpContainer);
   return helpContainer;
   },
   
   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
RenderHelp = function()
   {
   if(GetProductId()!=_PRODUCT.DTA.id)
      {
            
      $("main_div").innerHTML = GetHelpPageContent(GetProductId());
      var ExposeLinks = function()
         {
         switch(GetProductId())
            {
            case _PRODUCT.EDJE5110.id:
            case _PRODUCT.MEDIAHUBHD.id:
            case _PRODUCT.MEDIAHUBHD_422.id:
            case _PRODUCT.EN80.id:
            case _PRODUCT.HDMI2QAM.id:
            case _PRODUCT.YUV2QAM.id:
            case _PRODUCT.EN81.id:
            case _PRODUCT.EN91.id:
            case _PRODUCT.RD60.id:
            case _PRODUCT.EN20.id:
               $("manualDiv").style.display = ''; //Exposes link for user's manual
               $("apiNotesDiv").style.display = ''; //Exposes link to api notes
               break;
                     
            case _PRODUCT.SIGNEDJE.id:
            case _PRODUCT.EDJE4111.id:
            case _PRODUCT.SOLOIST411_HW2.id:
            case _PRODUCT.DPI.id:
            case _PRODUCT.SOLOISTHDPRO.id:
            case _PRODUCT.RD70.id:
            case _PRODUCT.EN40.id:
            case _PRODUCT.EN41.id:
            case _PRODUCT.EN10.id:
               $("apiNotesDiv").style.display = ''; //Exposes link to api notes
               break;
            }
         };
      YAHOO.util.Event.onAvailable("apiNotesDiv", ExposeLinks, this);
      }
   else//for DTA Only
      {
      window.location= "/help.html";
      }
   }, 
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetProductName = function()
   {
   return _product.name;
   },
      
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetProductColor = function()// highlighted top nav color
   {
   return _product.color;   
   }, 
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetNavColor = function()  // default (not highlighted top nav color)
   {
   return _product.navColor;
   }, 
      
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetSubNavColor = function()// highlighted sub nav color
   {
   return _product.subnavColor;
   }, 
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/ 
GetNumAudioInputs = function()
   {
   if(!IsInt(_product.numAudios))
      {
      return 0;
      }
   return _product.numAudios;
   },
   
   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
CreateProgramNumberOptions = function()
   {
   DomSelectReset($("programNumberSelect"));
   if(setting["dcmd_dpn_elements"]!==undefined)
      {
      for(var i=0; i<setting["dcmd_dpn_elements"].length; i++) 
         {
         var newOption = document.createElement("OPTION");
         newOption.text = setting["dcmd_dpn_elements"][i];
         newOption.value = setting["dcmd_dpn_elements"][i];
         $("programNumberSelect").options.add(newOption);
         }
      $("programNumberSelect").value = setting["dcmd_dpn_active"]; //select current index
      $("progNumberLabel").style.color = _ADTCOLOR.BLACK; //reset label color
      setting["dcmd_dpn_elements"] = null; //resets dpn elements once they've been consumed
      }
  
   },
   
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
InitAudioFlags = function()
   {
   for (var i=0; i<GetNumAudioInputs(); i++)
      {
      _unconfiguredAudio[i] = false;
      _countAudioErrors[i] = 0;
      }
   
   },
   
 
/***************************************
 * Clears info message 
 **************************************/   
ClearInfoMessage = function()
   {
   $("formStatusTop").innerHTML = '';
   $("formStatusBottom").innerHTML = '';
   _timeoutCode = null;
   }, 
   
/**********************************************************************************
 * Used to give feedback to users after an action (such as submitting a form) has 
 * been performed.  It can be used to display errors as well. 
**********************************************************************************/
SetInfoMessage = function
   (
   msg, //string w/ message to be displayed
   timeout, //in miliseconds...  amount of time message will be displayed
   color //(Optional) color that defines the style of the message
   )
   {
   var timeoutVal;
   if(timeout===undefined || timeout===null)
      {
      timeoutVal = _DEFAULT_INFO_MSG_TIMEOUT;   
      }
   else
      {
      timeoutVal = timeout;
      }
   if(_timeoutCode!==null)
      {//cancels previous timeout (if any)
      clearTimeout(_timeoutCode);
      } 
      
   //set style
   if((color!==undefined)&&(color!==null))
      {//set color   
      $("formStatusTop").style.color = color; 
      $("formStatusBottom").style.color = color;
      }
   else
      {//set default color
      $("formStatusTop").style.color = _ADTCOLOR.BLACK;
      $("formStatusBottom").style.color = _ADTCOLOR.BLACK;
      }
   $("formStatusTop").innerHTML = msg;
   $("formStatusBottom").innerHTML = msg;
   _timeoutCode = setTimeout(ClearInfoMessage, timeoutVal);
   }, 
   
/**********************************************************
 * Uses product index to determine if unit is a media player
 *********************************************************/   
IsPlayerUnit = function()
   {
   var result;
   switch(GetProductId())
      {
      case _PRODUCT.SIGNEDJE.id:
      case _PRODUCT.EDJE4111.id:
      case _PRODUCT.SOLOIST411_HW1.id:
      case _PRODUCT.SOLOIST411_HW2.id:
      case _PRODUCT.SOLOISTHDPRO.id:
         result = true;
         break;
      default:
         result = false;
         break;
      }     
   return result;
   }, 
   
   
   
 /**********************************************************
 * Uses product index to determine if unit is an encoder
 *********************************************************/   
IsEncoderUnit = function()
   {
   var result;
   switch(GetProductId())
      {
      case _PRODUCT.MEDIAHUBHD.id:
      case _PRODUCT.MEDIAHUBHD_422.id:
      case _PRODUCT.EDJE5110.id:
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
         result = true;
         break;
         
      default:
         result = false;
         break;
      }     
   return result;
   }, 
   
/**********************************************************
 * Uses product index to determine if unit is a qam
 *********************************************************/   
IsQamUnit = function()
   {
   var result;
   switch(GetProductId())
      {
      case _PRODUCT.HDMI2QAM.id:
      case _PRODUCT.YUV2QAM.id:
      case _PRODUCT.EN10.id:
      case _PRODUCT.EN20.id:
         result = true;
         break;
      default:
         result = false;
         break;
      }
   return result;
   }, 
   
   
/******************************************************************
*  Makes list items and trashcan as targets for drag&drop utility.
*  It also makes items draggable themselves, so they can be 
*  deleted by dragging them to the trashcan.
******************************************************************/
SetListItemsDragDrop = function
   (
   ulObj,
   ulType //type of ul item.  (scheduler, playlist, etc..)
   )
   {
   //Make list (including trashbin) droppable elements
   var listArray = ulObj.getElementsByTagName("li");
   
   for (var i = 0; i < listArray.length; i++) 
      {
      MakeListItemDD(listArray[i], ulType);   
      } //end for loop 
   },

/******************************************************************
*  Makes Playlists and trashcan as targets for drag&drop utility.
*  It also makes playlists draggable themselves, so they can be 
*  deleted by dragging them to the trashcan, or appended to another playlist
******************************************************************/
MakeListItemDD = function
   (
   lstItemObj, 
   ulType //type of unordered list (scheduler, playlist, etc).
   )
   {
   var 
      ddTarget = new YAHOO.util.DDTarget(lstItemObj),
      ddList = null,
      playlistXYArray = [],
      schLstXYArray = [],
      ddTargetId = ""
      ; //make li item droppable

   if(lstItemObj.id!=_TRASHBIN_ID) //trashcan is not draggable
      { 
      ddList = new YAHOO.util.DDProxy(lstItemObj.id); //make list item draggable
      
      //GETS XY coordinates of li item
      var GetListXY = function()
         {
         //scope is the li HTML element representing the list item
         switch(ulType)
            {
            case _ULTYPE.PLAYLIST:
               playlistXYArray[GetPlaylistIndex(this)] = _yuiDom.getXY(this.id);
               break;

            case _ULTYPE.SCHEDULE:
               schLstXYArray[GetSchLstIndex(this)] = _yuiDom.getXY(this.id);
               break;
            }
         };
      //Returns list item to its original XY coordinates after drag-drop event
      var ResetListXY = function()
         {
         //scope is the li HTML element representing the playlist item
         switch(ulType)
            {
            case _ULTYPE.PLAYLIST:
               _yuiDom.setXY(this.id, playlistXYArray[GetPlaylistIndex(this)], false);
               break;

            case _ULTYPE.SCHEDULE:
               _yuiDom.setXY(this.id, schLstXYArray[GetSchLstIndex(this)], false);
               break;
            }
         };
            
      ddList.on("b4DragEvent" , GetListXY , null, lstItemObj) ;
      
      ddList.endDrag = ResetListXY;
      
      ddList.onDragOver = function()
         {
         _yuiDom.addClass(arguments[1], 'over');  
         if (ddTargetId && (ddTargetId != arguments[1])) 
            {
            _yuiDom.removeClass(ddTargetId, 'over'); 
            } 
         ddTargetId = arguments[1];
         }; //ondragover end
      
      ddList.onDragOut = function() 
         {
         _yuiDom.removeClass(ddTargetId, 'over');
         };//ondragout end
      
      
      ddList.onDragDrop = function(ev) 
         {
         _yuiDom.removeClass(ddTargetId, 'over');
         switch(GetTargetType(ddTargetId))
            {
            case _TARGET_TYPE.TRASH: //deletes item
               switch(_currPage.id)
                  {
                  case _PAGE[_PAGEIDX.inv].id: //deletes playlist file from filesystem
                     RemovePlaylist(this.getEl());
                     break;

                  case _PAGE[_PAGEIDX.sch].id: //deletes schedule file from filesystem
                     RemoveSchedule(this.getEl());
                     break;
                  default:
                     break;
                  }
               
               break;
            
            case _TARGET_TYPE.PLAYLIST: //appends a playlist to another
              AppendPlaylist(this.getEl(), $(ddTargetId));
              break;
           
            case _TARGET_TYPE.SCHEDULE: //appends schedule events to another
               AppendSchedule(this.getEl(), $(ddTargetId));
               break; 
            }
      
         };//end ondragdrop
      }
   }, 
   
   
   
   
   
   
/***************************************************************************
 * Identifies the type of target where records are dropped.
 * Options are: 
 * PLAYLIST (To add item to a playlist), 
 * SCHEDLUE (To add item to a schedule),
 * RECORD (To re-arrange current playlist),
 * TRASH (To delete record from the filesystem, or from the current playlist) 
 * ERROR (Do nothing)
***************************************************************************/
GetTargetType = function
   (
   target
   )
   {
   //SET regular expressions
   var regexPlaylist =  new RegExp("^" + _PLAYLIST_ID_PREFIX);
   var regexSchedule =  new RegExp("^" + _SCH_LI_PREFIX);
   var regexRecord =    new RegExp("^yui-");
   var regexTrash =     new RegExp("^trash");
   
   var ret = _TARGET_TYPE.ERROR; //set error as default return value
   
   if(regexPlaylist.test(target))
      {
      ret = _TARGET_TYPE.PLAYLIST;
      }
   else if(regexRecord.test(target))
      {
      ret = _TARGET_TYPE.RECORD;
      }
   else if(regexSchedule.test(target))
      {
      ret = _TARGET_TYPE.SCHEDULE;
      }
   else if(regexTrash.test(target))
      {
      ret = _TARGET_TYPE.TRASH;
      }
   return ret;
   },
   
   
/*****************************************************************************
  *  Enables Drag-Drop functionality for all current records on the datatable
******************************************************************************/   
MakeRecordsDroppablebyDT = function
   (
   dt //datatable containing droppable records
   )
   {
    
   var recordSet = dt.getRecordSet(); //get records
   for(var i=0; i<recordSet.getLength(); i++)//foreach record
      {
      var rec = recordSet.getRecord(i); //get record
      var trEl = dt.getTrEl(rec); //get tr element
      var ddTarget = new YAHOO.util.DDTarget(trEl.id); //make record droppable 
      LogMyles("record " + trEl.id + " is now droppable");
      }    
   
   }, 
   
/****************************************************************
 * Sets the properties and renders the panel that will hold 
 * the system log messages.  Panel is hidden by default,
 * but it is ready to be displayed at the click of a button/image.
 ****************************************************************/
SetLogPanel = function()
   {
   
   if(GetProductId()==_PRODUCT.DTA.id)
      {
      HideHTMLElement($(_LOGPNLLINKID));
      }
   else  
      {
      ShowHTMLElement($(_LOGPNLLINKID));
      //sets click event listener  for Show Panel image
      _yuiEvent.addListener( // submit
         _LOGPNLLINKID, //id to attach event listener to 
         "click",  //type of event
         ShowLogPanel, //method to be invoked
         null, //object passed as argument
         false //set object as scope of handler
         );
      }
   },

/*****************************************************************
 * Hides the given markup element.
 * The argument can be the html element itself, 
 * or a string containing its id.   
 ******************************************************************/
HideHTMLElement = function
   (
   htmlEl
   )
   {
   var obj = null;
   if(typeof(htmlEl)=="string"){obj = $(htmlEl);}
   else if (typeof(htmlEl)=="object")
      {
      if((htmlEl.style.display!==null) &&(htmlEl.style.display!==undefined)){     obj = htmlEl;   }
      }
   if(obj!==null){obj.style.display = "none";}
   },
   
/*****************************************************************
 * Shows the given markup element.
 * The argument can be the html element itself, 
 * or a string containing its id.   
 ******************************************************************/
ShowHTMLElement = function
   (
   htmlEl
   )
   {
   var obj = null;
   if(typeof(htmlEl)=="string"){obj = $(htmlEl);}
   else if (typeof(htmlEl)=="object")
      {
      if((htmlEl.style.display!==null) &&(htmlEl.style.display!==undefined)){     obj = htmlEl;   }
      }
   if(obj!==null){obj.style.display = "";}
   },
   
   

   
   
  
   
/*
 * Detects if newtec demodulator is installed
 */
HasNewtecDemod = function()
   {
   
   return ((setting["sysd_sup_id"] !== undefined)&&(setting["sysd_sup_id"] !== null))&&
   (_NEWTEC_DEMOD_REGEX.test(setting["sysd_sup_id"])); //TODO: Replace magic value
   },
/*
 * Detects if adtec demodulator is installed
 */   
HasAdtecDemod = function()
   {
   return ((setting["sysd_sup_id"] !== undefined)&&(setting["sysd_sup_id"] !== null)&&(setting["sysd_sup_id"] == "ADT7201")); //TODO: Replace magic value
   }, 
   
   /*
    * Detects if a demodulator is installed
    */
HasDemod = function()
   {
   return (
            (setting["sysd_sup_id"] !== undefined) && 
            (setting["sysd_sup_id"] !== null)&&
            (
               (setting["sysd_sup_id"] == "ADT7201")||
               (_NEWTEC_DEMOD_REGEX.test(setting["sysd_sup_id"]))
            )
         ); 
   },
   
/********************************************************
 * Resets and populates the select object whose id is contained
 * in the first argument, w/ the array beign passed in the second 
 * argument (as coming from the AJAX request to the unit)
 *********************************************************/
SetProfileSelectOptions = function
   (
   selectObjId, 
   optionsArray
   )
   {
   
   var selObj = $(selectObjId);
   var defaultOpt = new Option();
   
   DomSelectReset(selObj); //reset object
   defaultOpt.value = _DEFAULT_PROFILE_VAL;
   defaultOpt.innerHTML = "--";

   try
      {
      selObj.add(defaultOpt, null);
      }
   catch(ex)
      {//IE
      selObj.appendChild(defaultOpt);
      }
   /* 
    * optionsArray e.g:
    * [ { "path": "\/media\/hd0\/dvc", "filename": "tnrT0.DVC" }, { "path": "\/media\/hd0\/dvc", "filename": "tnrT1.DVC" }, { "path": "\/media\/hd0\/dvc", "filename": "tnrT2.DVC" }] 
    */
   for(var i=0; i<optionsArray.length; i++)
      {
      var opt = new Option();
      opt.value = optionsArray[i].path + "\/" + optionsArray[i].filename;
      opt.innerHTML = TrimPrfPrefix(GetFileBasename(optionsArray[i].filename));
      try
         {
         selObj.add(opt, null);
         } 
      catch(e)
         {//IE
         selObj.appendChild(opt);
         }
      }
   
   selObj.value = _DEFAULT_PROFILE_VAL; //select default option
   },
   
/***************************************************************
 * Trims the profile prefix (if any) from the basename of the profile file. 
 **************************************************************/
TrimPrfPrefix = function(  prfName  )
   {
   var regex = /^(tnr|mod)(.+)$/i;
   if(regex.test(prfName))
      {
      return prfName.replace(regex, "$2");
      }
   return prfName;
   },
  
/***************************************************************************
 * Wrapper for _productInx global variable, to to obtain the product type. 
 * @return The product index of the unit.
 **************************************************************************/
GetProductId= function()
   {
   return _product.id;
   },
   
/*************************************************************************
 * Return an array of the available features based on the supplied key
 * and the product type.
 * @param key
 * @returns an array for a valid key and product type
 *           null on invalid key or invalid product type  
 ************************************************************************/
GetBoardFeatureKeyList = function
   (
   key //index of feature key list (1 based)
   )
   {
   var fkList = null;
   var featureKeys; 
   if (GetProductId() == _PRODUCT.RD60.id)
      {
      if (setting["sysd_sup_id_model"] == "7044")
         {
         featureKeys = 
            [
               null,
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"], 
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single MPEG TS or Generic Stream"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "High Symbol Rate", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)"]
            ];
         if (setting["sysd_sup_id_version"] == "BB")
            {
            var featureKeys2 = 
               [
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "no AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "no ACM client", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single MPEG TS", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 33 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"],
                  ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Adaptive Coding and Modulation", "Single TS/GS or Multiple Streams (Baseband Frames)", "ACM client enabled", "AES"]
               ];
            featureKeys = featureKeys.concat(featureKeys2);
            }
         }
      else if (setting["sysd_sup_id_model"] == "7072")
         {
         featureKeys =
            [
               null,
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"],
               ["DVB-DSNG", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Constant Coding and Modulation", "Single MPEG TS"]
            ];
         }
      if(key>featureKeys.length)
         {//Special case
         return ["ALL"];
         }
      fkList = featureKeys[key];
      }
   else if (IsENXX())
      {
      featureKeys = 
         [
            null,
            ["DVB-S1", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"],
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"],
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"],
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "No Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard Processing", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single MPEG TS or Generic Stream", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 5 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 15 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 30 Mbaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 45 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"], 
            ["DVB-S1", "DVB-S2", "QPSK", "8-PSK", "16-QAM/16APSK", "32APSK", "Symbol Rate <= 68 MBaud", "Single TS/GS or Multiple Streams (Baseband Frames)", "Standard ", "NCR Inserter", "Predistortion"] 
         ];
      fkList =  featureKeys[key];
      }
   return fkList;
   },
   
/*************************************************************************
 * Returns a boolean value determined by whether the supplied feature is
 * available using the supplied feature key.
 * @param feature
 * @param key
 * @returns {Boolean}
 ************************************************************************/
HasBoardFeature = function
   (
   feature,
   key
   )
   {
   var featureList = GetBoardFeatureKeyList(key);
   if ((featureList === undefined)||(featureList === null))
      {
      return false;
      }
   var x = featureList.length;
   while (x--)
      {
      if ((featureList[x] == feature) || (featureList[x] == "ALL"))
         {
         return true;
         }
      }
   return false;
   },
   
/*************************************************************************
 * Returns a string containing the list of features available with the
 * supplied feature key.
 * @param key
 * @returns {String}
 ************************************************************************/
GetBoardFeatureKeyDescription = function
   (
   key
   )
   {
   var featureDesc = "";
   var featureList = GetBoardFeatureKeyList(key);
   if ((featureList === undefined)||(featureList === null))
      {
      return featureDesc;
      }
   var x = featureList.length;
   while (x--)
      {
      if(featureList[x]=="ALL"){return "N/A";}
      featureDesc = featureList[x] + featureDesc;
      if (x > 0)
         {
         featureDesc = " + " + featureDesc;
         }
      }
   return featureDesc;
   },
   
/**************************************************************
 * Returns TRUE if the current product is of the ENN-XX line (EN-40, EN80, etc..).
 * Returns FALSE otherwise.
 *************************************************************/
IsENXX = function()
   {
   var result = false;
   switch(GetProductId())
      {
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
         result = true;
         break;
      
      case _PRODUCT.EN10.id:
      case _PRODUCT.EN20.id:
         //Default for these products because
         //they were not originally ENs.
         result = false;
         break;
      default:
         result = false; 
         break;
      }
   return result;
   },
   
   
   
/*************************************************************************************
 * On products that support it, this recursive routine prevents the device from getting 
 * too hot by continuously monitoring the internal temperature and warning the user in 
 * case over-heating is detected.
 * NOTE GE 09/09/2010
 * Currently, only ENxx products and MediaHub-HD422 support this feature.  But the 
 * design is scalable and can be implemented easily for other products if the hardware 
 * supports it. 
 ************************************************************************************/
MonitorTemperature = function()
   {
   if(IsENXX()||(GetProductId()==_PRODUCT.MEDIAHUBHD_422.id))
      {
      if(_thermostat===null){_thermostat = new ADTEC_THERMOSTAT();} //occurs only once
      _thermostat.monitor();
      setTimeout(MonitorTemperature, 3000);
      }
   },
   
 
/******************************************************************
 * Creates a Div element in the main body of the page, and returns
 * a reference to the newly created element.
 *****************************************************************/
CreatePanelDiv = function
   (
   elId //optional
   )
   {
   if((elId===undefined)||(typeof(elId)!="string")||
         ($(elId)!==undefined) //element id already exists
      )
      {
      elId = "randomDivId" + Math.floor(Math.random()*_MILLION);
      }
   var el = document.createElement("div");
   el.id = elId;
   if($("panelContainer").innerHTML !== ""){$("panelContainer").innerHTML = "";} //delete previous markup
   $("panelContainer").appendChild(el);
   return el;
   },
   
/********************************************
 * Sets the title of the document.
 * User will see this on the title bar of their
 * browser, and on the taskbar when this window
 * is active.  
 *******************************************/
SetDocumentTitle = function
   (
   deviceName //!< Optional
   )
   {
   if(deviceName!==undefined && deviceName!==null)
      {
      if(GetProductId()==_PRODUCT.EN91.id)
         {
         document.title = deviceName + " - EN-91 MPEG4 DSNG Encoder / Modulator - Adtec Digital";
         }
      else
         {
         document.title = deviceName + " - " + GetProductName() + " - Adtec Digital";
         }
      }
   else
      {//device name is not defined. Ask server
      var q=    '&q=SYSD+NA';
      var callback = 
         {
         success: function(o)
            {
            if(ParseResponse(o) && (setting["sysd_na"] !== undefined))
               {
               if(setting["sysd_na"]===undefined)
                  { //retry
                  SetDocumentTitle();
                  }
               else
                  {
                  if(GetProductId()==_PRODUCT.EN91.id)
                     {
                     document.title = setting["sysd_na"] + " - EN-91 MPEG4 DSNG Encoder / Modulator - Adtec Digital";
                     }
                  else
                     {
                     document.title = setting["sysd_na"] + " - " + GetProductName() + " - Adtec Digital";
                     }
                  }
               }
            else
               {//parser was not ready. retry
               SetDocumentTitle();
               }
            },
         failure: function(o)
            {
            document.title = GetProductName() + " - Adtec Digital";
            }
         };
      GetMyles(callback, q);
      }
   },

   
/****************************************************************************************************************
 * Returns TRUE if HD is allowed for this unit.  False otherwise.
 ***************************************************************************************************************/
IsHdAllowed = function()
   {
   return ((setting["sysd_fea_highdef"]===undefined)    ||   (setting["sysd_fea_highdef"]));
   },
   
/**********************************************************
 * Returns TRUE if a decoder is present and available.
 * Returns FALSE otherwise
 ***********************************************************/
DecoderPresent = function()
   {
   var result = false;
   switch(GetProductId())
      {
      case _PRODUCT.SIGNEDJE.id:
      case _PRODUCT.EDJE4111.id:
      case _PRODUCT.SOLOIST411_HW2.id:
      case _PRODUCT.MEDIAHUBHD.id:
      case _PRODUCT.MEDIAHUBHD_422.id:
      case _PRODUCT.RD60.id:
         result = true;
         break;
         
      default:
         result=false; 
         break;
      }
   return result;
   },
   
/*********************************************************
 * Adjusts log messages according to client's browser. 
 * Currently, only Mozilla is supported.  
 * NOTE:  global debug variable must be enabled in order
 * for log messages to appear.  Use for development only.
 *******************************************************/
LogMyles = function
   (
   logMsg
   )
   {
   if(_debug)
      {
      switch(GetBrowserType())
         {
         case _BROWSER.CHROME:
         case _BROWSER.MOZILLA:
            console.log(logMsg);
            break;
         
         case _BROWSER.IE:
            break;
         case _BROWSER.OPERA:
            break;
         case _BROWSER.KONQUEROR:
            break;
         case _BROWSER.SAFARI:
            break;
         default:
            break;
         }
      }
   },
/****************************************************************
 * Returns the id of the currently active page.
 ****************************************************************/
GetCurrentPageId = function()
   {
   return _currPage.id;
   },
   
   /***********************************************************
    * Returns verbose version of a streamType
    * NULL if err.
    ***********************************************************/
GetStreamType = function(terseVal)
   {
   var result = null;
   
   if(isNaN(terseVal)){terseVal = _STREAMTYPE.UNKNOWN;} //force unknown when a valkid number is not detected
   
   switch(terseVal)
      {
      
      case _STREAMTYPE.UNKNOWN:                           result = "--N/A--";         break;
      case _STREAMTYPE.ISO_IEC_11172_VIDEO:               result = "MPEG1";         break;
      case _STREAMTYPE.ISO_IEC_13818_VIDEO:               result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_11172_AUDIO:               result = "MP1";         break;
      case _STREAMTYPE.ISO_IEC_13818_AUDIO:               result = "MP2";         break;
      case _STREAMTYPE.ISO_IEC_13818_PRIVATE:             result = "MPEG2_PRIVATE";         break;
      case _STREAMTYPE.ISO_IEC_13818_PES_PRIVATE:         result = "MPEG2 ENCRYPTED";         break;
      case _STREAMTYPE.DVB_AC3_AUDIO:                     result = "AC3";         break;
      case _STREAMTYPE.ISO_IEC_13522_MHEG:                result = "ISO_IEC_13522_MHEG";         break;
      case _STREAMTYPE.DSM_CC:                            result = "DSM_CC";         break;
      case _STREAMTYPE.ITU_T_REC_H222_1:                  result = "ITU_T_REC_H222_1";         break;
      case _STREAMTYPE.ISO_IEC_13818_6_Type_A:            result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_13818_6_Type_B:            result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_13818_6_Type_C:            result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_13818_6_Type_D:            result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_13818_1_Aux:               result = "MPEG2";         break;
      case _STREAMTYPE.ISO_IEC_13818_7_AUDIO_AAC:         result = "AAC";         break;
      case _STREAMTYPE.ISO_IEC_13818_7_AUDIO_ADTS:        result = "MP2";         break;
      case _STREAMTYPE.ISO_IEC_14496_3_AUDIO:             result = "AAC";         break;
      case _STREAMTYPE.H264_VIDEO:                        result = "H264";         break;
      case _STREAMTYPE.AVC_VIDEO:                         result = "AVC";         break;
      case _STREAMTYPE.DCII_VIDEO:                        result = "DCII";         break;
      case _STREAMTYPE.AC3_AUDIO:                         result = "DD";         break;
      case _STREAMTYPE.DCII_SUBTITLES:                    result = "DCII_SUBTITLES";         break;
      case _STREAMTYPE.ADTEC_PMT:                         result = "ADTEC_PMT";         break;
      case _STREAMTYPE.ADTEC_PCR:                         result = "ADTEC_PCR";         break;
      case _STREAMTYPE.ADTEC_TELETEXT:                    result = "ADTEC_TELETEXT";         break;
      case _STREAMTYPE.ADTEC_SUBTITLE:                    result = "ADTEC_SUBTITLE";         break;
      case _STREAMTYPE.ADTEC_VBIDATA:                     result = "ADTEC_VBIDATA";         break;
      case _STREAMTYPE.ADTEC_VBITELETEXT:                 result = "ADTEC_VBITELETEXT";         break;
      case _STREAMTYPE.ADTEC_EMM:                         result = "ADTEC_EMM";         break;
      case _STREAMTYPE.ADTEC_ECM:                         result = "ADTEC_ECM";         break;
      case _STREAMTYPE.ADTEC_PAT:                         result = "ADTEC_PAT";         break;
      default:
         LogMyles("Unknown String Type found."); 
         result = "--N/A--";
         break;
      
      }
   
   return result;
   },
   
/**********************************************************************
 * Returns true if the given string is contained in the list of audio 
 * streamtypes. Returns false otherwise.
 *********************************************************************/
IsAudioStreamType = function(str)
   {
   var result = false;
   for(var i=0; i<_AUDIO_STREAMTYPE_STR_LIST.length; i++)
      {
      if(str==_AUDIO_STREAMTYPE_STR_LIST[i])
         {
         result = true; break;
         }
      }
   return result;
   },
   
/************************************************************************
 * Returns a boolean indicating if the board BQ11 or BQ12 is present
 * @return TRUE -  Board ID  BQ11 or BQ12 is present
 *         FALSE otherwise
************************************************************************/   
IsBQ11orBQ12 = function()
   {
      
   var result = false; //assume board id is not bq11 or bq12
   for(var i=0; i<_numPnpBoards; i++)
     {
     if(
        (setting["sysd_bi_id" +i].toUpperCase()=="BQ11")||
        (setting["sysd_bi_id" +i].toUpperCase()=="BQ12")
        )
        {
        result = true; 
        break;
        }
     }
   return result;
   },

IsBQ14 = function()
   {
   var result = false; //assume board id is not bq14
   for(var i=0; i<_numPnpBoards; i++)
     {
     if(
        (setting["sysd_bi_id" +i].toUpperCase()=="BQ14")
        )
        {
        result = true; 
        break;
        }
     }
   return result;
   },
   
IsBB14orBB15 = function()
   {
   var result = false; //assume board id is not bb14 or bb15
   for(var i=0; i<_numPnpBoards; i++)
     {
     if(
        (setting["sysd_bi_id" +i].toUpperCase()=="BB14")||
        (setting["sysd_bi_id" +i].toUpperCase()=="BB15")
        )
        {
        result = true; 
        break;
        }
     }
   return result;
   },
   
IsBB14 = function()
   {
   var result = false; //assume board id is not bb14 or bb15
   for(var i=0; i<_numPnpBoards; i++)
     {
     if(setting["sysd_bi_id" +i].toUpperCase()=="BB14")
        {
        result = true; 
        break;
        }
     }
   return result;
   },
   
IsBB15 = function()
   {
   var result = false; //assume board id is not bb14 or bb15
   for(var i=0; i<_numPnpBoards; i++)
     {
     if(setting["sysd_bi_id" +i].toUpperCase()=="BB15")
        {
        result = true; 
        break;
        }
     }
   return result;
   },
   
IsEn40_03 = function()
   {
   return ((GetProductId()==_PRODUCT.EN40.id)&&(IsBB14()));
   },
   
/****************************************************************************************
 * Returns TRUE if the hardware configuration support SDI Audio Matrix. False otherwise.
 ****************************************************************************************/
SupportsSdiAudioMatrix = function()
   {
   return(
      (GetProductId()==_PRODUCT.MEDIAHUBHD_422.id)||
      (IsENXX())||
      (GetProductId()==_PRODUCT.EN20.id)||
      (((GetProductId()==_PRODUCT.MEDIAHUBHD.id)||(GetProductId()==_PRODUCT.EDJE5110.id))&&(!IsBQ11orBQ12())));
   },
   
/************************************************************
 * Used to check existance and availability of a certain feature
 * @return TRUE If the given feature exists and it's enabled. 
 * @return FALSE otherwise
 *************************************************************/
HasFeature = function(featureKey)
   {
   var result = false;
   if (setting["sysd_fe"] !== undefined)
      {
      for(var i=0; i<setting["sysd_fe"].features.length; i++)
         {
         if(setting["sysd_fe"].features[i].name == featureKey.toLowerCase())
            {
            result = setting["sysd_fe"].features[i].state!==0;
            }   
         }
      
      }
   return result;
   
   },
   
GetPageUrl = function(pageIndex)
   {
   return '#' + _PAGE_ID + '=' + _PAGE_PREFIX + _PAGE[pageIndex].id;   
   },
   
   
/************************************************************
 * Adds static header for captions and teletext tables.
 ************************************************************/
AddVbhHeader = function(vbhTable)
   {
   var row =               document.createElement("tr");
   var lineCell =          document.createElement("td");
   var fidCell =           document.createElement("td");
   var countCell =         document.createElement("td");
   var lenCell =           document.createElement("td");
   var sdidCell =          document.createElement("td");
   row.color = "#707070";
   lineCell.bgColor =  "#AAAAAA";
   fidCell.bgColor =   "#AAAAAA";
   countCell.bgColor = "#AAAAAA";
   lenCell.bgColor =   "#AAAAAA";
   sdidCell.bgColor =   "#AAAAAA";
   
   lineCell.align =  "center";
   fidCell.align =   "center";
   countCell.align = "center";
   lenCell.align =   "center";
   sdidCell.align =   "center";
   
   lineCell.innerHTML =  "<b>Line Number</b>";
   fidCell.innerHTML =   "<b>Field ID</b>";
   countCell.innerHTML = "<b>Count</b>";
   lenCell.innerHTML =   "<b>Length</b>";
   sdidCell.innerHTML =   "<b>DID/SDID</b>";
   
   row.appendChild(lineCell);
   row.appendChild(fidCell);
   row.appendChild(countCell);
   row.appendChild(lenCell);
   row.appendChild(sdidCell);
   vbhTable.appendChild(row);
   },
   
  
/****************************************************************************************
 * Determine if firmware verion is Jaguar 2
 * NOTE GE 08/12/2011
 *    We need to figure out a way to detect the hardware configuration in a reliable way.
 *    Version number secondary digit should not be limited to 02 and 03.
 ****************************************************************************************/
IsJaguar2 = function()
   {
   var result = false; //default
   if(setting["sysd_banner_version"]!==undefined && setting["sysd_banner_version"]!==null)
      {
      result = setting["sysd_banner_version"].split(".")[1] == "02";
      }
   return result;
   },
   
/****************************************************************************************
 * Determine if firmware version is Jaguar 3
 * NOTE GE 08/12/2011
 *    We need to figure out a way to detect the hardware configuration in a reliable way.
 *    Version number secondary digit should not be limited to 02 and 03.
 ****************************************************************************************/
IsJaguar3 = function()
   {
   var result = false; //default
   if(setting["sysd_banner_version"]!==undefined && setting["sysd_banner_version"]!==null)
      {
      result = setting["sysd_banner_version"].split(".")[1] == "03";
      }
   return result;
   },

   
GetTerseAudioStreamType = function(pid)
   {
   var result = "";
   var s0Obj = setting["dcmd_s0"].status; 
   var smx = null;
   for(smx in s0Obj)
      {
      if(true) //Needed to satisfy jslint rule.  "The body of a for in should be wrapped in an if statement to filter unwanted properties from the prototype"
         {
         if(s0Obj[parseInt(smx, 10)].pid == pid)
            {
            result = s0Obj[parseInt(smx, 10)].streamType;
            break;
            }   
         }
      
      }
   return result;
   },
/***************************************************************************
 * Returns true if the PMT entry supplied as an argument is of type Audio.
 **************************************************************************/
IsPmtAudioEntry = function(entry)
   {
   var regex = /(\w+)\s+\(\d+\)/i;
   var result = false; //default response
   if(
      (entry.stream_type !== undefined) && (entry.stream_type!==null) &&  
      regex.test(entry.stream_type))
      {//not undefined, not null, and matches expected regex.
      switch(entry.stream_type.replace(regex, "$1").toUpperCase())
         {
         case "MPEG1_AUDIO":
         case "MPEG2_AUDIO":
         case "DVB_AC3_AUDIO":
         case "AAC":
         case "ISO_IEC_13818_7_AUDIO_ADTS":
         case "DOLBY_AC3"://stream type is of type audio
            result = true;
            break;
         case "ISO_IEC_13818_PES_PRIVATE": //for this streamtype, it is also necessary to identify a language to determine that this entry is an audio PID and not something else.
            result = (GetPmtAudioEntryLanguage(entry) !== null);
            break;
         default://not an audio entry.
            result=false;
         break;
         }
      }
   return result;
   },
   
/***************************************************************************
 * Returns true if the PMT entry supplied as an argument is of type Audio
 * and can be decoded
 **************************************************************************/
IsPmtAudioDecodableEntry = function(entry)
   {
   var regex = /(\w+)\s+\(\d+\)/i;
   var result = false; //default response
   if(
      (entry.stream_type !== undefined) && (entry.stream_type!==null) &&  
      regex.test(entry.stream_type))
      {//not undefined, not null, and matches expected regex.
      switch(entry.stream_type.replace(regex, "$1").toUpperCase())
         {
         case "MPEG1_AUDIO":
         case "MPEG2_AUDIO":
         case "DVB_AC3_AUDIO": 
         case "DOLBY_AC3":
         
         /*
          * NOTE GE 11/30/2011:
          * AAC is not currently supported, but it will be in the future.
          * Simply delete this note, and uncomment the line below when that occurs.
          */
         
//         case "AAC":  
            result = true;
            break;
         case "ISO_IEC_13818_PES_PRIVATE":
//            result = (GetPmtAudioEntryLanguage(entry) !== null);
            result = HasValidAudioDescriptor(entry);
            break;
            
         default://not an audio entry.
            result=false;
         break;
         }
      }
   return result;
   },

/***************************************************************************
 * Returns true if the PMT entry supplied as an argument is of type Audio
 * and can be used as PASSTHRU
 **************************************************************************/
IsPmtAudioPassthruEntry = function(entry)
   {
   var regex = /(\w+)\s+\((\d+)\)/i;
   var result = {"result": false, "streamtype": -1}; //default response
   if(
      (entry.stream_type !== undefined) && (entry.stream_type!==null) &&  
      regex.test(entry.stream_type))
      {//not undefined, not null, and matches expected regex.
      switch(entry.stream_type.replace(regex, "$1").toUpperCase())
         {
         case "ISO_IEC_13818_7_AUDIO_ADTS":
         case "DVB_AC3_AUDIO": 
         case "AAC":  
         case "DOLBY_AC3":
            result.result = true;
            result.streamtype = parseInt(entry.stream_type.replace(regex, "$2"), 10);
            break;
         case "ISO_IEC_13818_PES_PRIVATE": //for this streamtype, it is also necessary to identify a language to determine that this entry is an audio PID and not something else.
            result.result = (GetPmtAudioEntryLanguage(entry) !== null);
            result.streamtype = parseInt(entry.stream_type.replace(regex, "$2"), 10);
            break;
         default://not an audio entry.
            result.result =false;
         break;
         }
      }
   return result;
   },

/*********************************************************************************
 * Searches through the descriptors of the given audio entry for the language corresponding to such entry.
 * If no language is found, "N/A" is returned.
 **********************************************************************************/
GetPmtAudioEntryLanguage = function(entryObj)
   {
   var result = null;
   if((entryObj.es_descriptors!==undefined) && (entryObj.es_descriptors instanceof Array))
      {
      for(var i=0; i<entryObj.es_descriptors.length; i++)
         {
         if((entryObj.es_descriptors[i].data.language !== undefined) && (entryObj.es_descriptors[i].data.language !== null))
            {
            result = entryObj.es_descriptors[i].data.language;
            break;
            }
         }
      }
   return result;
   },
   
   
HasValidAudioDescriptor = function(entryObj)
   {
   var result = false;
   if((entryObj.es_descriptors!==undefined) && (entryObj.es_descriptors instanceof Array))
      {
      for(var i=0; i<entryObj.es_descriptors.length; i++)
         {
         if((entryObj.es_descriptors[i].tag !== undefined) && (entryObj.es_descriptors[i].tag !==  null))
            {
            switch((entryObj.es_descriptors[i].tag).toUpperCase())
               {
               case "REGISTRATION (5)":
                  if(   (entryObj.es_descriptors[i].data.format_identifier !== undefined) && 
                        (entryObj.es_descriptors[i].data.format_identifier !== null) &&
                        ((entryObj.es_descriptors[i].data.format_identifier).toUpperCase()=="BSSD")   )
                     {
                     result = true;
                     }
                  break;
                  
                  //Add additional cases here
               case "DESCRIPTOR_TAG_AC3 (61)":
               case "AC3 (106)":
                  result = true;
                  break;
               }            
            }
         }
      }
   return result;
   },
/***************************************************************************
 * Returns TRUE if hardware supports Encoder Latency. Returns FALSE otherwise.
 **************************************************************************/
SupportsEncoderLatency = function()
   {
   return (GetProductId()==_PRODUCT.MEDIAHUBHD_422.id) || IsENXX();
   },
   
/*****************************************************************************
 * Returns the hardware configuration for RD units.
 ******************************************************************************/   
GetRdHwConf = function()
   {
   var result = _RDHWCONF.NO_DEMOD; //assume no demodulator is present
   if(!HasDemod())
      {
      result = _RDHWCONF.NO_DEMOD;
      }
   else if(HasAdtecDemod())
      {
      result = _RDHWCONF.ADTEC_DEMOD;
      }
   else if(HasNewtecDemod())
      {
      result = _RDHWCONF.NEWTEC_DEMOD;
      }
   return result;
   },
  

/*******************************************************************************
 * Returns TRUE if more than 1 codec is supported by the hardware
 ******************************************************************************/
SupportsCodecModeChange = function()
   {
   return ((GetProductId()==_PRODUCT.MEDIAHUBHD_422.id) || (IsENXX() && (GetProductId()!=_PRODUCT.EN91.id)));
   },
   
   
/*************************************************************************
 * Given an enum val, returns the URL for the corresponding Decrypt Image.
 * If the given value is out of bounds, the default value is a the URL of
 * a transparent image.
 **************************************************************************/
GetDecryptImageUrlByEnumVal = function(statusEnum)
   {
   var result = ""; 
   if(isNaN(statusEnum) || (statusEnum<0) || (statusEnum>_DECRYPTSTATUSARRAY.length))
      {
      result = "/images/none.gif";
      }
   else
      {
      result = "/images/" + _DECRYPTSTATUSIMGARRAY[statusEnum];
      }
   return result;
   },
   
//Returns true if the current unit supports boardsinfo command
SupportsBoardsInfo = function()
   {
   var result = false;
   switch(GetProductId())
      {
      case _PRODUCT.HDMI2QAM.id:
      case _PRODUCT.YUV2QAM.id:
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
      case _PRODUCT.RD60.id:
      case _PRODUCT.EN10.id:
      case _PRODUCT.EN20.id:
         result = true;
         break;
      }
   return result;
   },
/******************************************************************************
 * Returns true if the current resolution is HD.  False otherwise.
 *******************************************************************************/   
IsHdResolution = function()
   {
   var result = false;
   if((setting["ecmd_hsize"] !== undefined) && (setting["ecmd_vsize"] !== undefined))
      {
      if((parseInt(setting["ecmd_hsize"], 10)>=_MIN_HD_HSIZE)||(parseInt(setting["ecmd_vsize"], 10)>=_MIN_HD_VSIZE))
         {
         result = true;
         } 
      }
   return result;
   },

/******************************
 * Initializes and renders a modal panel
 ******************************/
InitModalPanel = function(bodyMarkup, header)
   {
   if((header===undefined) || (header===null))
      {
      header = "<b>Adtec Digital</b>";
      }
   
   if(($(_MODALCONTAINERDIV)===undefined) ||($(_MODALCONTAINERDIV)===null) )
      {
      var mdContDiv = document.createElement("div");
      mdContDiv.id = _MODALCONTAINERDIV;
      document.body.insertBefore(mdContDiv, document.body.firstChild);
      }
   var panelConf = 
      {
      modal:true, width: "300px", visible:true, autofillheight: "body", close:false, draggable:true
      };
   if(_globalModalPanel!==null){_globalModalPanel=null;}
   _globalModalPanel = new YAHOO.widget.Panel(_MODALCONTAINERDIV, panelConf);
   _globalModalPanel.setBody(bodyMarkup);
   _globalModalPanel.setHeader(header);
   _globalModalPanel.render();
   _globalModalPanel.center(); 
   },
   
/***********************************************
 * Hides the Modal Panel, if currently rendered.
 ************************************************/
CloseModalPanel = function()
   {
   if(_globalModalPanel!==null)
      {
      _globalModalPanel.hide();
      }
   },
   

/***********************************************************
 * Initializes and renders the panel to hold the thumbnail.
 * Returns the panel object for further manipulation
 **********************************************************/
RenderThumbnailPanel = function(header)
   {
   if((header===undefined) || (header===null))
      {
      header = "<b>Adtec Digital</b>";
      }
   
   var thumbnailPanelBody = '<center><img id="' + _DCDRTHUMBNAIL_ID + '" src="' + _DCDRTHUMBNAIL_SRC + '" /></center>';
   if(IsCanvasSupported())
      {
      thumbnailPanelBody += '<br /><br />'
         +  '<table id="audioThumbnailTable" bgcolor="black">'
//         +  '<tr><td colspan="16"><h5>Audio</h5></td></tr>'
         +  '<tr>'
         +  '<td colspan="16"><canvas id="' + _DCDR_CANVAS_PREFIX + '" width="' + _DCDR_CANVAS_WIDTH + '" height="' + _DCDR_CANVAS_HEIGHT + '"></canvas></td>'
         +  '</tr>'
         +  '<tr>'
         ;
      for(var i=0; i<_DCDR_CANVAS_NUM_AUDIOS; i++)
         {
         thumbnailPanelBody += '<td id="audioBarFooterTd' + i + '">' + (i+1) + '</td>';
         }
      
      thumbnailPanelBody += [
         '</tr>',
         '</table>'
         ].join("");
         
      }
   
   if(($(_THUMBNAILCONTAINERDIV)===undefined) ||($(_THUMBNAILCONTAINERDIV)===null) )
      {
      var mdContDiv = document.createElement("div");
      mdContDiv.id = _THUMBNAILCONTAINERDIV;
      document.body.insertBefore(mdContDiv, document.body.firstChild);
      }
   var width = "220px";
   var height = "350px";
   
   var alignContext = (!IsMobile())? null : //only declare context for mobile platforms
                        [
                       "thumbnailAlignDiv", //element to be aligned with
                       "bl",  //align bottomleft of anchor
                       "tl",  // with topleft of panel 
                          [
                          "beforeShow",//before showing
                          "windowResize"
                          ]
                       ];
   var panelConf = 
      {
      "width": width, 
      "height": height, 
      "underlay": "matte",
      "modal":false, 
      "close":true, 
      "visible":false, 
      "draggable":true, 
      "context":    alignContext 
      };
  
   var thumbnailPanel = new YAHOO.widget.Panel(_THUMBNAILCONTAINERDIV, panelConf);
   var context;
   var OnThumbnailRender = function()
      {
      var canvas = $(_DCDR_CANVAS_PREFIX);
      context= canvas.getContext("2d");
      };
   thumbnailPanel.renderEvent.subscribe(OnThumbnailRender);
   
   thumbnailPanel.setBody(thumbnailPanelBody);
   
   thumbnailPanel.setHeader(header);
   thumbnailPanel.render();
   thumbnailPanel.center(); 
   OnThumbnailHide = function()      
      {
      clearTimeout(_videoThumbnailTimeout);      
      clearTimeout(_audioThumbnailTimeout);
      };
      
   thumbnailPanel.hideEvent.subscribe(OnThumbnailHide);
   return {"panel":thumbnailPanel, "ctx": context};
   },
   
   
/***********************************************
 * Hides the Thumbnail Panel, if currently rendered.
 ************************************************/
CloseThumbnailPanel = function()
   {
   if(this.hide){this.hide();}
   },
   
/***********************************************
 * Displays the thumbnail panel
 ************************************************/
ShowThumbnailPanel = function()
   {
   var MAX_AUDIO_LEVEL = 524288,
   MIN_DECIBELS = -40,
   MAX_DECIBELS = 0,
   MED_DBS_THRESHOLD = 50, //%
   HIGH_DBS_THRESHOLD = 75, // %
   PASSTHRU_AUDIO_BAR_COLOR = "#E0AB1B", //Amber color
   LOW_DBS_COLOR = "#00FF00", //Green
   MED_DBS_COLOR = "#FCE808", //Yellow
   HIGH_DBS_COLOR = "#FF0000"; //Red
   
   var controller = this;
   if(controller.panel.show)
      {
      controller.panel.show();
      }
   
   var getNewImg = function()
      {
      _videoThumbnailTimeout = setTimeout(getNewImg, 2000); 
      $(_DCDRTHUMBNAIL_ID).src = _DCDRTHUMBNAIL_SRC + "?" + Math.random();
      };
   var getNewAudioValues = function()
      {
      var callback = 
         {
         
         success: function(o)
            {
            var response = _yuiParseJson(o.responseText);
            var scaleFactor = _DCDR_CANVAS_HEIGHT/100;
            var x=0, y=0;
            var val = [];
            var dbs = [];
            var isPt = [];
            for(var i=0; i<_DCDR_CANVAS_NUM_AUDIOS; i++)
               {
               isPt[i] = (setting["dcmd_s0"] && setting["dcmd_s0"].status && setting["dcmd_s0"].status[i] && (setting["dcmd_s0"].status[i].srcType == _SMX_STATUS_SRCTYPE.PASSTHRU));
               if(isPt[i])
                  {
                  $("audioBarFooterTd" + i).innerHTML = "P";
                  continue;
                  }
               $("audioBarFooterTd" + i).innerHTML = "" + (i+1);
               dbs[i] = response[i]/MAX_AUDIO_LEVEL; 
               dbs[i] = (Math.log(dbs[i])/_LN10)*20;
               
               // Values less than -40dB goto 0
               if (dbs[i] <= MIN_DECIBELS)
                  {
                  val[i] = 0;
                  } 
               else 
                  {
                  dbs[i] += MAX_DECIBELS-MIN_DECIBELS;
                  val[i] = dbs[i] / (MAX_DECIBELS-MIN_DECIBELS);
                  val[i] *= 100.0;
                  }
               }
            
            for(y=0; y<_DCDR_CANVAS_HEIGHT; y+=scaleFactor)
               {
               x=0;
              
               var rectColor = ((_DCDR_CANVAS_HEIGHT-y)/scaleFactor)>HIGH_DBS_THRESHOLD? HIGH_DBS_COLOR : ((_DCDR_CANVAS_HEIGHT-y)/scaleFactor)>MED_DBS_THRESHOLD? MED_DBS_COLOR: LOW_DBS_COLOR; 
                        
               for(var j=0; j<_DCDR_CANVAS_NUM_AUDIOS; j++)
                  {
                  if(isPt[j])
                     {//passthru detected
                     controller.ctx.beginPath();
                     controller.ctx.rect(x, y, _DCDR_CANVAS_AUDIO_WIDTH, scaleFactor);
                     controller.ctx.fillStyle = PASSTHRU_AUDIO_BAR_COLOR;
                     controller.ctx.fill();
                     }
                  else if(y>=(_DCDR_CANVAS_HEIGHT - scaleFactor*val[j]))
                     {
                     controller.ctx.beginPath();
                     controller.ctx.rect(x, y, _DCDR_CANVAS_AUDIO_WIDTH, scaleFactor);
                     controller.ctx.fillStyle = rectColor;
                     controller.ctx.fill();
                     }
                  else
                     {
                     controller.ctx.clearRect(x, y, _DCDR_CANVAS_AUDIO_WIDTH, scaleFactor);
                     }
                  x+= _DCDR_CANVAS_AUDIO_WIDTH + _DCDR_CANVAS_AUDIO_DELIM_WIDTH;
                  }
               }
            },
         failure: function(o){}
         };
      
      var postdataObj = 
         {//build post arguments object
         "id": _REQID.GETRDAUDIOVALUES
         }; 
      
      var postdataStr = _yuiStringify(postdataObj); //transform object to string 
      ConnectToReqHandler(callback, postdataStr, false);
      
      _audioThumbnailTimeout = setTimeout(getNewAudioValues, 2000); 
      };
      
   if(IsCanvasSupported())
      {
      getNewAudioValues();
      } //Audio Thumbnail requires HTML5 Canvas element 
   getNewImg();
   },

/*******************************************************************************
 * converts terse responses for audio type into user friendly labels
 ******************************************************************************/

GetAudioType = function(terseType)
   {
   var verboseType;
   
   switch(terseType)
      {
      case "DD":
      case "DD-06":
         verboseType = "Dolby Digital AC3";
         break;
      case "--":
         verboseType = "Musicam Layer I (No longer supported)";
         break;
                     
      case "MU":
      case "MU-04":
         verboseType = "MPEG 1 Layer 2";
         break;
                     
      case "DE":
         verboseType = "Dolby E";
         break;  
      
      case "LP":
         verboseType = "Linear PCM";
         break;  
      
      default:
         verboseType = "Unknown"; //highly unlikely
         break;
      }
   return verboseType;
   },

/*******************************************************************************
 * converts terse responses for encode status into user friendly labels
 ******************************************************************************/
GetEncodeStatus = function(enumStatus)
   {
   switch(enumStatus)
      {
      case "0":
      case "00":
         return "INITIALIZING";
      case "1":
      case "01":
         return "IDLING";
      case "2":
      case "02":
         return "STOPPING";
      case "3":
      case "03":
         return "ENCODING";
      case "4":
      case "04":
         return "CUEING";
         
      }
   
   return "UNKNOWN STATUS";
   
   },

/*******************************************************************************
 * returns the file name of the image (LED) to display, according to the encode
 * status
 ******************************************************************************/

GetEncodeImage = function(enumStatus)
   {
   
   switch(enumStatus)
      {
      case "0":
      case "00":
      case "4":
      case "04":
      case "1":
      case "01":
         return "yellow.gif"; //"INITIALIZING" or CUEING
      
      case "2":
      case "02":
         return "red.gif"; //"STOPPING";
      case "3":
      case "03":
         return "green.gif"; //"ENCODING";
            
      }
   return "nolight.gif"; //unknown status
   
   },

/*******************************************************************************
 * converts terse responses fro decode status into user friendly labels
 ******************************************************************************/

GetDecodeStatus = function(enumStatus)
   {
   var ret;
   
   switch(parseInt(enumStatus, 10))
      {
      case 0:
         ret = "UNIT NOT READY";
         break;
   
      case 1:
         ret = "IDLE";
         break;
         
      case 2:
         ret = "IDLE CUEING";
         break;
         
      case 3:
         ret = "IDLE NEXT";
         break;
         
      case 4:
         ret = "STOP";
         break;
         
      case 5:
         ret = "PLAYING";
         break;
         
      case 6:
         ret = "BUFFERED";
         break;
         
      case 7:
         ret = "WARNING";
         break;
         
      case 8:
         ret = "FATAL";
         break;
         
      case 9:
         ret = "NEXT";
         break;
         
      case 10:
         ret = "PREVIOUS";
         break;
         
      case 11:
         ret = "PAUSED";
         break;
         
      case 12:
         ret = "PAUSE CUEING";
         break;
         
      case 13:
         ret = "PAUSE NEXT";
         break;
      case 14:
         ret = "REWIND";
         break;
             
      case 15:
         ret = "MULTICAST RECEIVE";
         break;
         
      case 16:
         ret = "SLOW";
         break;
         
      case 17:
         ret = "INDEX";
         break;
         
      case 18:
         ret = "CUESPOT";
         break;
         
      case 19:
         ret = "PLAYSPOT";
         break;
         
      case 20:
         ret = "DVB-ASI RECEIVING";
         break;
         
      case 21:
         ret = "CONF. DECODE";
         break;
         
      default:
         ret = "UNKNOWN STATUS";
         break;
             
      }
   return ret;
   
   },

/*******************************************************************************
 * returns the file name of the image LED to display, according to the current
 * status
 ******************************************************************************/

GetDecodeImage = function(enumStatus)
   {
   var ret;
   switch(parseInt(enumStatus, 10))
      {
      case 0:
      case 12:
      case 1:
      case 2:
      case 3:
      case 6:
         ret = "yellow.gif"; //"WARNING", PAUSE CUEING, or UNIT NOT READY
         break;
         
      case 4:
      case 8:
         ret = "red.gif"; // "FATAL", or STOPPING
         break;
         
      default: //every other case, including PLAYING, MULTICAST RECEIVING, PLAYSPOT, etc..
         ret = "green.gif";
         break;
      }
   return ret;
   
   },

/*******************************************************************************
 * returns the file name of the image LED to display, according to the current
 * status
 ******************************************************************************/
GetDecodeImage_dpi = function(enumStatus)
   {
   var result = "nolight.gif";
   switch (enumStatus) 
      {
      case "0":
      case "00":
         result = "red.gif";
         break;
      case "1":
      case "01":
      case "5":
      case "05":
         result = "green.gif";
         break;

      case "2":
      case "02":
         result = "yellow.gif";
         break;


      default: // every other case, including PLAYING, MULTICAST RECEIVING, PLAYSPOT, etc..
         result = "nolight.gif";
         break;
      }
   return result; 
   },

/*******************************************************************************
 * converts terse responses for fec param into user friendly labels
 ******************************************************************************/
GetFECParam = function(terseType)
   {
   var verboseType;

   switch (terseType) 
      {
      case 0:
         verboseType = "OFF";
         break;

      case 1:
         verboseType = "ON";
         break;

      case 2:
         verboseType = "MAXBURST";
         break;

      case 3:
         verboseType = "BURST";
         break;

      case 4:
         verboseType = "LOW LATENCY";
         break;

      default:
         verboseType = "Unknown"; // highly unlikely
      }
   return verboseType;
   },

/*******************************************************************************
 * converts terse responses
 ******************************************************************************/

GetRTP = function(terseType)
   {
   var verboseType;
   switch (terseType) 
      {
      case "OFF":
         verboseType = "UDP";
         break;
      case "ON":
         verboseType = "RTP";
         break;

      default:
         verboseType = "Unknown"; // highly unlikely
      }
   return verboseType;
   },

   // TODO: Doc
GetEasModeVerbose = function()
   {
   
   var result = '';
   var audio = setting["ecmd0_eas_audio"];
   var video = setting["ecmd0_eas_video"];
   if((audio=="OFF")&&(video=="OFF"))
      {
      result = "OFF";
      }
   else if((audio=="OFF")&&(video=="ON"))
      {
      result = "Video Only";
      }
   else if((audio=="ON")&&(video=="OFF"))
      {
      result = "Audio Only";
      }
   else if((audio=="ON")&&(video=="ON"))
      {
      result = "Video and Audio";
      }
   else
      {
      //TODO: Log error
      }
   return result;
   },

/*******************************************************************************
 * Returns verbose version of decoder source (ASI, RFx, IP). NULL if err.
 ******************************************************************************/
GetDecoderSource = function(terseVal)
   {
   var result = null;
   var decSource = ["ASI", "RF1", "RF2", "IP"];   //NOTE GE 1/20/2011: Must be in synch w/ enum TDcdrInput (firmware). If one changes, so must the other.
   if((!isNaN(terseVal))&&(terseVal>=0) && (terseVal<decSource.length))
      {
      result = decSource[terseVal];
      }
   return result;
   },

/*******************************************************************************
 * Returns verbose version of the decoder status NULL if err.
 ******************************************************************************/
GetDecoderStatus = function(terseVal)
   {
   var result = null;
   var DEC_STATUS = ["N/A", "STOPPED", "DECODING", "PAUSED", "STOPPING", "FEA_LOCKED", "ENCRYPTED", "MAX"]; //NOTE GE 1/20/2011: Must be in synch w/ enum TDecStatus (firmware). If one changes, so must the other.
   if((!isNaN(terseVal))&&(terseVal>=0) && (terseVal<DEC_STATUS.length))
      {
      result = DEC_STATUS[terseVal];
      }
   return result;
   },

/*******************************************************************************
 * Returns verbose version of the decoder source status NULL if err.
 ******************************************************************************/
GetDecoderSourceStatus = function(terseVal)
   {
   var result = null;
   var DEC_SRC_STATUS = ["NO INPUT", "PROGRAM NOT FOUND", "ACTIVE"]; //NOTE GE 1/20/2011: Must be in synch w/ enum TDecSrcStatus (firmware). If one changes, so must the other.
   if((!isNaN(terseVal))&&(terseVal>=0) && (terseVal<DEC_SRC_STATUS.length)) //check for array boundary
      {
      result = DEC_SRC_STATUS[terseVal];
      }
   return result;
   },

/*******************************************************************************
 * Returns verbose version of the decoder audio status NULL if err.
 ******************************************************************************/
GetDecoderAudioStatus = function(terseVal)
   {
   var result = null;
   var DEC_AUD_STATUS = [ "INIT", "HALT", "MUTE", "INGRESS", "DEC","EGRESS", "PTSALIGN", "PTSALIGN_MUTE", "PTSALIGN_INGRESS", "PTSALIGN_DEC", "PTSALIGN_EGRESS"]; //NOTE GE 1/20/2011: Must be in synch w/ enum TDecSrcStatus (firmware). If one changes, so must the other.
   if((!isNaN(terseVal))&&(terseVal>=0) && (terseVal<DEC_AUD_STATUS.length)) //check for array boundary
      {
      result = DEC_AUD_STATUS[terseVal];
      }
   return result;
   },

/*******************************************************************************
 * Returns the verbose version of a chroma NULL if err.
 ******************************************************************************/
GetChroma = function(terseVal)
   {
   var result = null;
   var chromaArray = ["0", "420", "422", "444"];
   if((!isNaN(terseVal)) && (terseVal>=0) && (terseVal<chromaArray.length))
      {
      result = chromaArray[terseVal];
      }
   return result;
   },

/*******************************************************************************
 * Returns the verbose version of a chroma NULL if err.
 ******************************************************************************/
HasQmod = function()
   {
   var x;
   for (x = 0; x < _numPnpBoards; x++)
      {
      if (/^PC82.*/.test(setting["sysd_bi_name" + x]))
         {
         return true;
         }
      }
   return false;
   },

/*******************************************************************************
 * Returns true if the current hardware supports the NS command.
 ******************************************************************************/
SupportsNameserver = function()
   {
   return (GetProductId() != _PRODUCT.DTA.id) ||  ((!IsJaguar2()) && (!IsJaguar3()));
   },
   
/*******************************************************************************
 * Changes the display name of a page.
 ******************************************************************************/
ChangePageName = function(pageId, pageName)
   {
   _PAGE[pageId].name = pageName;
   },
   
/*********************************************************
 * Aids in the validation process. Called once for every input field,
 * it verifies that input is an integer within the valid range   
 *********************************************************/   
PIDValidate = function(error, value, type)
   {
   var errFlag = false;
   if(isNaN(parseInt(value, _DEFAULT_NUM_BASE))) //input is not a valid integer
      {
      error.str += type + " PID is not a valid number.<br />";
      errFlag = true;
      }
   else if( (value < _MIN_PID_VAL) || (value > _MAX_PID_VAL) ) //input is not within the valid range 
      {
      error.str += type + " PID is outside the valid ranges <" + _MIN_PID_VAL + ", " + _MAX_PID_VAL + ">(dec) or (0x" + _MIN_PID_VAL.toString(_HEXNUMBASE) + "-0x" + _MAX_PID_VAL.toString(_HEXNUMBASE) + ")<br />";
      errFlag = true;
      }
   return !errFlag;
   },
   
/*********************************************************
 *  Constructor for error string object   
 *********************************************************/
PidStringObject = function()
   {
   this.str = "<b>Please correct the following errors:</b> <br />"; 
   },
   
/*************************************************************************************
 * TODO: Doc?
 *************************************************************************************/    
FormatHex = function(hexVal)
   {
   hexVal = Trim(hexVal.replace('0x', ''));
   while (hexVal.length > 4 && hexVal.charAt(0) == '0') 
      {
      hexVal = hexVal.substring(1);
      }
   while (hexVal.length < 4) 
      {
      hexVal = '0' + hexVal;
      }
   return '0x' + hexVal;
   },
   
/***********************************************************************************************************
 * Event handler video rate changes
 ***********************************************************************************************************/    
OnVideoRateChange = function(rateObj)
   {
   var val = parseFloat(Trim(rateObj.value));
   if(val<1000000.00) { rateObj.value = (val * 1000000) + '';  }
   },
   
/*************************************************************************************
 * Check frame rate to determine US or Eurpean format.
 *************************************************************************************/
IsUSFormat = function(frate, table)
   {
   if (frate === undefined)
      {
      return table != "DVB";
      }
   return (frate == "29i" || frate == "59p");
   },
   
/************************************************************************
 * Event handler for rate change
 ************************************************************************/
OnMuxRateChange = function(rateObj)
   {
   var val = parseFloat(Trim(rateObj.value));
   if(IsENXX())
      {
      if (val >= _MIN_TMR) 
         {
         rateObj.value = (val / _MILLION) + '';
         }
      }
   else
      {
      if (val < _MIN_TMR) 
         {
         rateObj.value = (val * _MILLION) + '';
         }
      }
   },
   
GetVerboseAfd = function(terseAfd)
   {
   var terseAfdInt = parseInt(terseAfd, 10),
   verboseTable = ["OFF", "WSS", "BOX16:9_T", "BOX14:9_T", "BOX16:9_C", "AS_CODEFRAME", "4:3_C", "16:9_C", "14:9_C", "4:3_SP_14:9_C", "16:9_SP_14:9_C", "16:9_SP_4:3_C"];
   return ((!isNaN(terseAfdInt)) && (terseAfdInt>=0) && (terseAfdInt<verboseTable.length)) ? verboseTable[terseAfdInt]: "N/A";
   },
/***********************************************************************
 * Returns TRUE if the hardware supports Advanced Satellite Features.
 * Returns FALSE otherwise.
 ***********************************************************************/
SupportsSatelliteFeatures = function(o)
   {
   return ((IsENXX()  &&  IsNtModSupported()) || 
      ((GetProductId()== _PRODUCT.RD60.id) && HasNewtecDemod()));
   },

/***************************************************************************************************
 * Returns the status opf the product key.  Always TRUE for devices that do not require a product key
 ****************************************************************************************************/
HasValidProductKey = function()
   {
   var i=0,
   result = false,
   PRD_KEY_NAME = 
      [
      "N/A", //unknown         0
      "N/A", //NA              1
      "N/A", //signEdje        2
      "N/A", //edje-4111          3
      "N/A", //NA              4
      "N/A", //soloist-4111_hw2   5
      "N/A", //dta               6
      "PdDPI", //dpi          7
      "N/A", //NA              8
      "N/A", //NA              9
      "N/A", //mediahub-hd      10
      "N/A", //SoloistHD_Pro     11
      "PdMHD422", //mHUB-HD422       12
      "PdE5110", //edje-5110         13
      "PdH2QAM", //hdmi2qam           14
      "PdRD70", //RD-70           15
      "PdRD60",//RD-60            16
      "PdEN40", //EN-40            17
      "PdEN80", //EN-80            18
      "PdY2QAM", //yuv2qam           19
      "PdEN41", //EN-41           20
      "PdEN81", //EN-81           21
      "PdEN91", //EN-91            22
      "PdEN10", //EN-10          23
      "PdEN20" //EN-20          24
      ];
   switch(GetProductId())
      {
      case _PRODUCT.DTA.id:  // dta
      case _PRODUCT.DPI.id: // dpi       (not enforced)
      case _PRODUCT.SIGNEDJE.id: //signEdje
      case _PRODUCT.EDJE4111.id: //edje-411
      case _PRODUCT.SOLOIST411_HW2.id: //soloist-4111_hw2     
      case _PRODUCT.SOLOISTHDPRO.id: // SoloistHD_Pro
      case _PRODUCT.MEDIAHUBHD.id:     //mediahub-hd
         result = true;  //These devices do not have product keys..  
         break;
      
         
      case _PRODUCT.MEDIAHUBHD_422.id: //mHUB_HD422
      case _PRODUCT.EDJE5110.id:       //edje-5110  
      case _PRODUCT.EN40.id:       //EN-40         
      case _PRODUCT.EN80.id:       //EN-80     
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
      case _PRODUCT.HDMI2QAM.id:       //hdmi2qam
      case _PRODUCT.YUV2QAM.id:        //yuv2qam
      case _PRODUCT.EN20.id:           //EN20
      case _PRODUCT.EN10.id:           //EN10
      case _PRODUCT.RD60.id:       //rd-60
         var prdKey = PRD_KEY_NAME[GetProductId()].toLowerCase();
         
         for(i=0; i<setting.sysd_fe.features.length; i++)
            {
            if(prdKey == setting.sysd_fe.features[i].name)
               {
               result = (setting.sysd_fe.features[i].state > 0);
               break;
               }            
            }
         break;
      }
   return result;
   },
   
/*****************************************************
 * Returns the Standard header for the status panel.  
 * This is common to all Adtec devices.
 *****************************************************/
GetStatusPanelStdHeader = function()
   {
   var result =''
      +  '<div class="headercontainer">'
      +  '<div id="logo" class="logo">'
      +     '<img src="/images/' + GetProductName() + '_logo.gif" alt="' + GetProductName() + '"></img>'
      +  '</div>'
      +  '<div id="versionDiv" class="version"></div>'
      +  '</div>'
      +  '<br/>'
      ;
   return result;
   }
   ;/*****************************************************************************
* @file
* @author Original: German Escallon
* @author Contributors: Michael Turner
* @date Created: 
* @date Last Edit: $Date$ by $Author$
* Description: Handles the dropdown options (Selects) for the User Interface
******************************************************************************/

/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/ 
var GetSelectOptions = function
   (
   type
   )    
   {
   var ret = '', i;
   switch(type)
      {
      
      case "pid_rit":
      case "rdOsdBlink":
      case "rdOsdMode":
      case "rdOsdSvcMode":
      case "audio_ecc":
      
         ret = ''
            +     '<option value="0">OFF</option>'
            +     '<option value="1">ON</option>'
            ;
         break;
         
      case "system_snmp":
      case "system_gbe":
      case "network_bark":
      case "network_xcp":
      case "streaming_rtp":
      case "encoder_videoAutoFill":
      case "display_startupMode":
      case "display_autoFormat":
      case "decoder_confdecode":
      case "decoder_confidenceDecodeAutoRes":
      case "encoder_spt":
      case "decoder_decoderActiveFormat":
      case "services_startUp":
      case "pid_vbiMode":
      case "encoder_dvbAsiReceiveMode":
      case "easNetTrig":
         ret = ''
            +     '<option value="OFF">OFF</option>'
            +     '<option value="ON">ON</option>'
            ;
         break;
          
      case "system_timezone":
         ret = ''
            +  '<option id="" value="" selected>Local time</option>'
            +  '<option id="x-9" value="-9">Alaska Standard Time(GMT-9)</option>'
            +  '<option id="x-8" value="-8">Alaska Daylight Time(GMT-8)</option>'
            +  '<option id="AST-4" value="-4">Atlantic Standard Time (GMT-4)</option>'
            +  '<option id="ADT-3" value="-3">Atlantic Daylight Time (GMT-3)</option>'
            +  '<option id="x-1" value="-1">Azores (GMT-1)</option>'
            +  '<option id="x4" value ="4">Baku (GMT +4)</option>' 
            +  '<option id="x7" value="7">Bangkok (GMT +7)</option>'
            +  '<option id="x-3" value="-3">Brazilia (GMT-3)</option>'
            +  '<option id="CST-6" value="-6">Central Standard Time (GMT-6)</option>'
            +  '<option id="CDT-5" value="-5">Central Daylight Time (GMT-5)</option>'
            +  '<option id="x6" value="6">Dhakar (GMT +6)</option>' 
            +  '<option id="EST-5" value="-5">Eastern Standard Time (GMT-5)</option>'
            +  '<option id="EDT-4" value="-4">Eastern Daylight Time (GMT-4)</option>'
            +  '<option id="x-12" value="-12">Eniwetok (GMT-12)</option>'
            +  '<option id="x12" value="12">Fiji (GMT +12)</option>'
            +  '<option id="GMT0" value="0">Greenwich Mean Time (GMT)</option>' 
            +  '<option id="x-10" value="-10">Hawaii-Aleutian (GMT-10)</option>'
            +  '<option id="x8" value="8">Hong Kong (GMT +8)</option>'
            +  '<option id="x2" value="2">Israel (GMT +2)</option>' 
            +  '<option id="x11" value="11">Magadan (GMT +11)</option>'
            +  '<option id="x-2" value="-2">Mid-Atlantic (GMT-2)</option>'
            +  '<option id="x3" value="3">Moscow (GMT +3)</option>'
            +  '<option id="MST-7" value="-7">Mountain Standard Time (GMT-7)</option>'
            +  '<option id="MDT-6" value="-6">Mountain Daylight Time (GMT-6)</option>'
            +  '<option id="x5" value="5">New Delhi (GMT +5)</option>' 
            +  '<option id="x-5" value="-5">New York (GMT -5 EST)</option>'
            +  '<option id="PST-8" value="-8">Pacific Standard Time (GMT-8)</option>'
            +  '<option id="PDT-7" value="-7">Pacific Daylight Time (GMT-7)</option>'
            +  '<option id="x1" value="1">Rome (GMT +1)</option>'
            +  '<option id="x-11" value="-11">Samoa (GMT-11)</option>'
            +  '<option id="x10" value="10">Sydney (GMT +10)</option>'
            +  '<option id="x9" value="9">Tokyo (GMT +9)</option>'
            ;
         break;
            
      case "audio_audioLevel":
         for(i=_ENC_ALV_MIN_VAL; i<_ENC_ALV_MAX_VAL; i++){  ret += '<option value="' + i + '">' + i + '</option>';  }
         break;
         
      case "audio_musicamMode":
         ret = ''
            +  '<option value="STEREO">STEREO</option>'
            +  '<option value="MONO">MONO</option>'
            +  '<option value="DUALMONO">DUAL MONO</option>'
            ;  
         break;
         
      case "audio_audioInput":
         ret = ''
            +  '<option value="ANALOG">ANALOG</option>'
            +  '<option value="SDI">SDI</option>'
            +  '<option value="AES">AES</option>'
            ;  
         break;
         
      case "audio_mode":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="ENCODE">ENCODE</option>'
            +  '<option value="PASSTHRU">PASSTHRU</option>'
            ; 
         break;
         
      case "audio_mode_mh422_3_4":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="ENCODE">ENCODE</option>'
            ;
         break;
         
     case "audio_output_mode":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="DECODE">DECODE</option>'
            +  '<option value="PASSTHRU">PASSTHRU</option>'
            ;  
           
         break;   
         
      case "audio_audioGroup_422":
         ret = ''
            +  '<option value="1">Group 1 and 2</option>'
            +  '<option value="3">Group 3 and 4</option>'
            ;  
         break;

      case "audio_clockSrc":
         ret = ''
            +  '<option value="0">Embedded</option>'
            +  '<option value="1">Video</option>'
            ;
         break;
     
         
      case "audio_audioGroup":
         ret = ''
            +  '<option value="1">1</option>'
            +  '<option value="2">2</option>'
            +  '<option value="3">3</option>'
            +  '<option value="4">4</option>'
            ;  
         break;   
         
         
      case "audio_frequency":
         ret =  ''
            +  '<option value="32000">32000</option>'
            +  '<option value="44100">44100</option>'
            +  '<option value="48000">48000</option>'
            ;  
         break;
         
      case "audio_audioType":

         ret = ''
            +  '<option value="DD">DD AC3 0x81</option>'
            +  '<option value="MU">MU 0x03</option>'
            +  '<option value="DE">DOLBY E /5.1/2.0</option>'
            +  '<option value="LP">Linear PCM / E2</option>'
            +  '<option value="DD-06">DD AC3 0x06</option>'
            +  '<option value="MU-04">MU 0x04</option>'
            ;
            
         break;
       
       case "audio_output_audioType":
         ret = ''
            +  '<option value="DE">DOLBY E /5.1/2.0</option>'
            +  '<option value="LP">LINEAR PCM / E2</option>'
            ;  
         break;        
         
      case "audio_audioMatrix":
         if(SupportsSdiAudioMatrix() && (!IsENXX()))
            {
            ret = ''//innerHTML markup dynamically set when loading audio tab
               +  '<option value="1">&nbsp;</option>'
               +  '<option value="3">&nbsp;</option>'
               +  '<option value="5">&nbsp;</option>'
               +  '<option value="7">&nbsp;</option>'
               ;
            }
         else if(IsENXX())
            {
            ret = ''
               +  '<option value="1">Group 1 - 1/2</option>'
               +  '<option value="2">Group 1 - 3/4</option>'
               +  '<option value="3">Group 2 - 5/6</option>'
               +  '<option value="4">Group 2 - 7/8</option>'
               +  '<option value="5">Group 3 - 9/10</option>'
               +  '<option value="6">Group 3 - 11/12</option>'
               +  '<option value="7">Group 4 - 13/14</option>'
               +  '<option value="8">Group 4 - 15/16</option>'
               ;  
            }
         break;
         

     case "audio_codingMode":
            ret = ''
            +  '<option value="1">1/0</option>'
            +  '<option value="2">2/0</option>'
            ;  
         break;
         
      case "audio_bitstreamMode":
            ret = ''//TODO: Replace magic numbers
            +  '<option value="0">Main</option>'
            +  '<option value="1">Main-Dialogue</option>'
            +  '<option value="2">Visually Impaired</option>'
            +  '<option value="3">Hearing Impaired</option>'
            +  '<option value="4">Dialog</option>'
            +  '<option value="5">Commentary</option>'
            +  '<option value="6">Emergency Flash</option>'
            +  '<option value="7">Voice Over</option>'
            +  '<option value="8">Main-Karaoke</option>'
            ;  
         break;
          
      case "audio_dialogNormalization":
      case "audio_mixingLevel":
         for(i=1; i<=31; i++) //TODO: Replace magic number
            {//add one option for 1 - 31
            ret +=   '<option value="' + i + '">' + i + '</option>';
            }
              
         break; 
      
      case "audio_productionInfo":   
         ret = '' //TODO: Replace magic numbers
          + '<option value="0">DOES NOT EXIST</option>'
          + '<option value="1">EXIST</option>'
          ;
         break;        
          
     
      case "audio_roomType":   
         ret = ''//TODO: Replace magic numbers
          + '<option value="0">NOT INDICATED</option>'
          + '<option value="1">LARGE ROOM</option>'
          + '<option value="2">SMALL ROOM</option>'
          ;
         break; 
     
      case "audio_copyright":
      case "audio_rfOverModulation":        
         ret = ''//TODO: Replace magic numbers
          + '<option value="0">NO PROTECTION</option>'
          + '<option value="1">PROTECTION</option>'
          ;
         break;
         
      case "audio_original":       
         ret = ''//TODO: Replace magic numbers
          + '<option value="0">COPY</option>'
          + '<option value="1">ORIGINAL</option>'
          ;
         break;          
         
      case "audio_lineModeCompression":
      case "audio_rfModeCompression":       
         ret = ''//TODO: Replace magic numbers
          + '<option value="0">NONE</option>'
          + '<option value="1">FILM STANDARD</option>'
          + '<option value="2">FILM LIGHT</option>'          
          + '<option value="3">MUSIC STANDARD</option>'            
          + '<option value="4">MUSIC LIGHT</option>'            
          + '<option value="5">SPEECH</option>'           
          ;
         break;          

      case "audio_fullRangeLPF":
      case "audio_fullRangeDCFilter":       
         ret = ''//TODO: Replace magic numbers
          + '<option value="0">DISABLE</option>'
          + '<option value="1">ENABLE</option>'
          ;
         break;  
              
      case "display_crawlDirection":
         
         ret = '<option value="R2L">RIGHT TO LEFT</option>';
         break;           
      
      case "display_videoPosition":
      case "osd_position":
         ret += ''
            +  '<option value="DEFAULT">Select Position</option>'
            +  '<option value="C">CENTER</option>'
            +  '<option value="TR">TOP RIGHT</option>'
            +  '<option value="TL">TOP LEFT</option>'
            +  '<option value="BR">BOTTOM RIGHT</option>'
            +  '<option value="BL">BOTTOM LEFT</option>'
            ;
         
         break;
      
      case "display_spdifMode":
         ret += ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="UNCOMPRESSED">UNCOMPRESSED</option>'
            +  '<option value="COMPRESSED">COMPRESSED</option>'
            +  '<option value="PASSTHROUGH">PASSTHROUGH</option>'
            ;
         break;
      
      case "display_style":
         ret += ''
            +  '<option value="OFF">SINGLE OSD</option>'
            +  '<option value="NTSCFULL">NTSC w/Crawl</option>'
            +  '<option value="PALFULL">PAL w/Crawl</option>'
            +  '<option value="720FULL">720 w/Crawl</option>'
            +  '<option value="1080FULL">1080 w/Crawl</option>'
            ;
            
         break;
         
      case "display_videoScaling":
      case "osd_scaling":
         if(type=="display_videoScaling")
            {
            ret+= '<option value="OFF">OFF</option>'; //additional option for video scaling
            }
         for(i=100; i>0; i--)
            {
            ret+= '<option value="' + i + '">' + i + '%</option>';
            }
         break;    
      case "easMode":
         ret = ''
            + '<option value="OFF">OFF</option>'
            + '<option value="AUDIO_VIDEO">AUDIO + VIDEO</option>'
            + '<option value="AUDIO">AUDIO ONLY</option>'
            + '<option value="VIDEO">VIDEO ONLY</option>'
               ;
         break;
      case "inventory_repeat":
         ret = ''
            +  '<option value="ONE">ONE</option>'
            +  '<option value="ALL">ALL</option>'
            +  '<option value="LAST">LAST</option>'
            ;
         break;
          
      case "network_hostMode":
         ret = ''
            +  '<option value="CLIENT">Client</option>'
            +  '<option value="MIRRORLIST">MirrorList</option>'
            +  '<option value="MIRRORCLIENT">MirrorClient</option>'
            ;
         if(GetProductId()==_PRODUCT.DPI.id)//CCMS optionj available for DPI only
            {
            ret += '<option value="CCMS">CCMS</option>';
            }
         break;

      case "network_stc":
         ret = ''
            +  '<option value="0">OFF</option>'
            +  '<option value="1">1 - Slave (single)</option>'
            +  '<option value="100">100 - Master (single)</option>'
            ;
         for( i=1; i<=9; i++)
            {
            ret += '<option value="'+i+'0">'+i+'0 - Slave  (multiple)</option>' ;
            }
         
         for( i=1; i<=9; i++)
            {
            ret += '<option value="1'+i+'0">1'+i+'0 - Master  (multiple)</option>' ;
            }
         break;

      case "pid_teletextType_1":
          ret = ''         
             +  '<option value="1">INITIAL</option>'
             +  '<option value="2">SUBTITLE</option>'
             +  '<option value="3">ADDLINFO</option>'
             +  '<option value="4">PGMSCHED</option>'
             +  '<option value="5">SUBTITLEHI</option>'
            ;
          break;         
         
      case "pid_teletextType_2":
         ret = ''
            +  '<option value="0">OFF</option>'    
            + GetSelectOptions("pid_teletextType_1") //recursive call for easy maintenance
            ;
         break;
      
      case "pid_teletextMagNum":
         for( i=0; i<8; i++){ ret += '<option value="'+i+'">'+i+'</option>'; }
         break;
      
      case "service_tables":
         ret = ''
            +     '<option id="DVB" value="DVB">DVB</option>'
            +     '<option id="MPEG" value="MPEG">MPEG</option>'
            +     '<option id="ATSC" value="ATSC">ATSC</option>'
            ;
         break;
    
      case "service_closedCaption":
       ret = ''
            +     '<option value="OFF">OFF</option>'
            +     '<option value="ATSC">ATSC 608</option>'
            +     '<option value="ATSC708">ATSC 708</option>'
            +     '<option value="ATSCCONVERT">ATSC 608 -> 708</option>'            
            +     '<option value="DVS157">DVS157</option>'
            ; 
         break;
      
      case "service_vbiSource":
         ret = ''
            +     '<option value="COMPOSITE">COMPOSITE</option>'
            +     '<option value="SDI">SDI</option>'
            ;
           break;       
        
      case "service_asiMode":
         ret = ''
            +     '<option value="CONTINUOUS">CONTINUOUS</option>'
            +     '<option value="ENCODEONLY">ENCODE ONLY</option>'
            ;
         break; 
         
      case "service_encoderLatency":
         ret = ''
            +     '<option value="3">LONG</option>'
            +     '<option value="0">NORMAL</option>'
            +     '<option value="1">LOW</option>'
            +     '<option value="2">VERY LOW</option>'
            ;
         if(GetProductId()==_PRODUCT.EN91.id)
            {
            ret += '<option value="4">100LAT</option>';
            }
         break; 
      
      
      
      case "service_serviceType":
         ret = ''
            +     '<option value="0">CABLE</option>'
            +     '<option value="1">SATELLITE</option>'
            +     '<option value="2">TERRESTRIAL</option>'
            ;
         break;     
       
         
      case "service_fecInner":    
         ret = ''  
          + '<option value="1">1/2</option>'
          + '<option value="2">2/3</option>'
          + '<option value="3">3/4</option>'
          + '<option value="4">5/6</option>'
          + '<option value="5">7/8</option>'
          + '<option value="6">8/9</option>'
          + '<option value="15">NO CODING</option>' 
          ;
         break;    
 
      case "service_fecOuter":  
         ret = ''
            +     '<option value="1">NO CODING</option>'
            +     '<option value="2">RS (204/188)</option>'
            ;
         break;   

      case "service_polarization":   
         ret = ''
            +     '<option value="0">HORIZONTAL LINEAR</option>'
            +     '<option value="1">VERTICAL LINEAR</option>'
            +     '<option value="2">LEFT CIRCULAR</option>'
            +     '<option value="3">RIGHT CIRCULAR</option>'            
            ;
         break;        

      case "service_positionFlag": 
         ret = ''
            +     '<option value="0">WEST</option>'
            +     '<option value="1">EAST</option>'
           ;
         break;          

      case "service_bandwidth": 
         ret = ''
            +     '<option value="0">8 MHZ</option>'
            +     '<option value="1">7 MHZ</option>'
            +     '<option value="2">6 MHZ</option>'
           ;
         break;    
         
      case "service_hierarchyInfo":  
         ret = ''
            +     '<option value="0">NONE</option>'
            +     '<option value="1">1</option>'
            +     '<option value="2">2</option>'
            +     '<option value="3">4</option>'
            ;
         break;             
         
      case "service_codeRateLPStream":
         ret = ''
            +     '<option value="0">1/2</option>'
            +     '<option value="1">2/3</option>'
            +     '<option value="2">3/4</option>'
            +     '<option value="3">5/6</option>'
            +     '<option value="4">7/8</option>'
            ;
         break;              
         
      case "service_guardInterval":
         ret = ''
            +     '<option value="0">1/32</option>'
            +     '<option value="1">1/16</option>'
            +     '<option value="2">1/8</option>'
            +     '<option value="3">1/4</option>'
            ;
         break;     
        
      case "service_transmitMode": 
         ret = ''
            +     '<option value="0">2k</option>'
            +     '<option value="1">8k</option>'
            ;
         break;     

      case "service_otherFrequencyFlag": 
         ret = ''
            +     '<option value="0">NONE</option>'
            +     '<option value="1">1 OR MORE</option>'
            ;
         break;
      case "service_annex":
         ret = ''
            +     '<option value="A">A</option>'
            +     '<option value="B">B</option>'
            +     '<option value="C">C</option>'
            ;
         break;
      case "service_dvbType": 
         ret = ''
            +     '<option value="0">DVB-S</option>'
            +     '<option value="1">DVB-S2</option>'
            ;
         break;
         
      case "service_dvb2Rolloff":
         ret = ''
            +     '<option value="0">35%</option>'
            +     '<option value="1">25%</option>'
            +     '<option value="2">20%</option>'
            ;
         break;
         
      case "service_multicastMode":
         ret = ''
            +     '<option value="OFF">OFF</option>'
            +     '<option value="SEND">SEND</option>'
            ;
         break;

         
      case "service_multicastConnector":
         ret = ''
            +     '<option value="ETHERNET">ETHERNET</option>'
            +     '<option value="GIGE">GIGE</option>'
            ;
         break;
         
      case "ip_mcast_connector":
         ret = ''
            +     '<option value="0">ETHERNET</option>'
            +     '<option value="1">GIGE</option>'
            ;
         break;
         
      case "ip_msts":
         ret = ''
            +     '<option value="1">ENC1 (SPTS)</option>'
            +     '<option value="2">ENC2 (SPTS)</option>'
            +     '<option value="0">Both (MPTS)</option>'
            ;
         break;
         
      case "service_fec":
         ret = ''
            +     '<option value="' + _FECVAL.off + '">OFF</option>'
            +     '<option value="' + _FECVAL.on + '">ON</option>'
            +     '<option value="' + _FECVAL.maxburst + '">MAXBURST</option>'
            +     '<option value="' + _FECVAL.burst + '">BURST</option>'
            +     '<option value="' + _FECVAL.lowlatency + '">LOWLATENCY</option>'
            ;
         break;             
      
      case "service_tos":
         ret = ''
            +     '<option value="0">NORMAL</option>'
            +     '<option value="2">MINIMIZE COST</option>'
            +     '<option value="4">MAXIMIZE RELIABILITY</option>'
            +     '<option value="8">MAXIMIZE THROUGHPUT</option>'
            +     '<option value="16">MINIMIZE DELAY</option>'
            ;
         break;
         
      case "services_closedCaption":
       ret = ''
           +     '<option value="OFF">OFF</option>'
           +     '<option value="ATSC">ATSC 608</option>'
           +     '<option value="ATSCCONVERT">ATSC 608 -> 708</option>'            
           +     '<option value="DVS157">DVS157</option>'                 
            ; 
          break;   
          
     case "services_input_hdmi":
       ret = ''
            +     '<option value="HDMI">HDMI</option>'         
            +     '<option value="COMPOSITE">COMPOSITE</option>'
            ; 
          break;
          
     case "services_input_yuv":
        ret = ''
           +     '<option value="YUV">YUV</option>'
           +     '<option value="COMPOSITE">COMPOSITE</option>'
           ;
        break;
        
     case "services_input_sdi":
         ret = ''
            +     '<option value="SDI">SDI</option>'
            +     '<option value="COMPOSITE">COMPOSITE</option>'
            ;
         break;
         
     case "services_audioOptions":
         ret = ''
              +     '<option value="audioEM">Encode MPEG 1 Layer 2</option>'
              +     '<option value="audioPD">Pass Dolby Digital</option>'     
         ;
         if (setting["ecmd0_ads_mdsp0"] != "ABSENT")
            {
            ret += ''
              +     '<option value="audioED">Encode Dolby Digital</option>'     
              ; 
            }
            break;
          
      case "services_audioInput":
         if(GetProductId()==_PRODUCT.HDMI2QAM.id)
            {
            ret = '<option value="HDMI">HDMI</option>';
            }
         else if(GetProductId()==_PRODUCT.YUV2QAM.id || GetProductId()==_PRODUCT.EN10.id)
            {
            ret = '<option value="SPDIF">SPDIF</option>';
            }
         else if(GetProductId()==_PRODUCT.EN20.id)
            {
            ret = '<option value="SDI">SDI</option>'
            + '<option value="SPDIF">SPDIF</option>';
            }
         ret  +=  '<option value="ANALOG">ANALOG</option>';
         break;
         
     case "modulator_qamMode":
       ret = ''                 
            +     '<option value="64">64</option>'         
            +     '<option value="256">256</option>'                
            ; 
          break;   

     case "modulator_videoType":
         ret = ''                 
              +     '<option value="NTSC">NTSC</option>'         
              +     '<option value="PAL">PAL</option>'                
              ; 
            break;                 
          
     case "modulator_qamEncoding":
       ret = ''          
            +     '<option value="ANNEX_A">ANNEX A</option>'
            +     '<option value="ANNEX_B">ANNEX B</option>'
            ; 
          break;        
          
      case "modulator_upConvertorPower":
         ret = '';
         for( i=45; i<=56; i++) //TODO: Replace magic values
            {
            ret +=   '<option value="'+i+'">'+i+'</option>';
            }
          break; 

      case "modulator_qamInvert":
         ret = ''          
            +     '<option value="NORMAL">NORMAL</option>'
            +     '<option value="INVERTED">INVERTED</option>'
            ;
          break;           
      
      
      case "pid_paradigm":
         ret = ''
            +     '<option value="null"> -- Select -- </option>'
            +     '<option value="adtec">Adtec Digital</option>'
            +     '<option value="tandberg">Tandberg</option>'
            +     '<option value="atscpgm3">ATSC PGM 3</option>'
            +     '<option value="atscpgm4">ATSC PGM 4</option>'
            +     '<option value="atscpgm5">ATSC PGM 5</option>'
            +     '<option value="atscpgm6">ATSC PGM 6</option>'
            +     '<option value="atscpgm7">ATSC PGM 7</option>'
            +     '<option value="atscpgm8">ATSC PGM 8</option>'
            +     '<option value="atscpgm9">ATSC PGM 9</option>'
            +     '<option value="tiernan">Tiernan</option>'
            +     '<option value="wbu">WBU-ISOG</option>'
            ;
         for(i=0; i<_NUM_EBU_PARADIGMS; i++)
            {
            ret += '<option value="ebu' + i + '">EBU ' + (i+1) + '</option>';
            }
         break;
         
      case "service_constantCapture":
         ret = ''
            +     '<option value="OFF">TRANSMISSION ONLY</option>'
            +     '<option value="ON">CAPTURE TO DRIVE</option>'
            ;
         break;
      
      case "teletext_ptx_mode":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="WAVEFORM">WAVEFORM</option>'
            +  '<option value="OP47">OP47</option>'
            ;
         break;

      case "vbi_vbpMode":
         ret = ''
            +  '<option value="0">OFF</option>'
            +  '<option value="1">EUROTEXT</option>'
            ;
         break;
      
      case "vbi_vbpStart":
         ret = '';
         for( i=6; i<=22; i++)
            {
            ret +=   '<option value="'+i+'">'+i+'</option>';
            }
         break;
      
      case "vbi_vbpNum":
         ret = '';
         for( i=1; i<=16; i++)
            {
            ret +=   '<option value="'+i+'">'+i+'</option>';
            }
         break;
         
      case "audio_feedbackPath":   
          ret = ''
              +     '<option value="OFF">OFF</option>'
              +     '<option value="ON">ON</option>'
              +     '<option value="GHOST">GHOST</option>'   
              ;
           break;
           
      case "service_rtp":
         ret = ''
            +     '<option value="OFF">OFF - Use UDP</option>'
            +     '<option value="ON">ON - Use RTP</option>'
            ;
         break;
      
      case "encoder_afd": //active format descriptor options
         ret = ''
            +     '<option value="OFF">OFF</option>'
            +     '<option value="WSS">WSS</option>'
            +     '<option value="BOX16:9_T">16:9 TOP ALIGNED</option>'
            +     '<option value="BOX14:9_T">14:9 TOP ALIGNED</option>'
            +     '<option value="BOX16:9_C">16:9 CENTER</option>'
            +     '<option value="AS_CODEDFRAME">FULL FRAME</option>'
            +     '<option value="4:3_C">4:3 CENTER PILLARBOX</option>'
            +     '<option value="16:9_C">16:9 CENTER LETTERBOX</option>'
            +     '<option value="14:9_C">14:9 CENTER LETTERBOX</option>'
            +     '<option value="4:3_SP_14:9_C">4:3 WITH SHOOT AND PROTECT 14:9 CENTER</option>'
            +     '<option value="16:9_SP_14:9_C">16:9 WITH SHOOT AND PROTECT 14:9 CENTER</option>'
            +     '<option value="16:9_SP_4:3_C">16:9 WITH SHOOT AND PROTECT 4:3 CENTER</option>'
            ;
 
         break;
                
      case "encoder_sdiVideoMode":
         ret = ''
            +  '<option value="AUTO">AUTO</option>'
            +  '<option value="SD">SD</option>'
            +  '<option value="HD1.4G">HD 1.4G</option>'
            ;
         break;
         
      case "encoder_faultMode":
          ret = ''
             +  '<option value="00">480I 59.94</option>'
             +  '<option value="01">576I 50</option>'
             ;

             if ((GetProductId() != _PRODUCT.EN40.id) && (GetProductId() != _PRODUCT.EN41.id))  
                {//          EN4Xs cannot do High Definition  fault modes... the chip is not capable.
                ret +=  '<option value="02">720P 59.94</option>'
                   +  '<option value="03">720P 50</option>'
                   +  '<option value="04">1080I 59.94</option>'
                   +  '<option value="05">1080I 50</option>'
                   ;
                }
          break;    
         
      case "decoder_smxPair":
         ret = ''
            +  '<option value="1">Group 1 - 1/2</option>'
            +  '<option value="3">Group 1 - 3/4</option>'
            +  '<option value="5">Group 2 - 5/6</option>'
            +  '<option value="7">Group 2 - 7/8</option>'
            ;
         break;
         
      case "decoder_smxTrack":
         ret = ''
            + '<option value="1">1</option>'
            + '<option value="3">2</option>'
            + '<option value="5">3</option>'
            + '<option value="7">4</option>'
            ;
         break;
     
      case "encoder_videoInput":
         ret = ''
            +  '<option value="SDI">SDI</option>'
            +  '<option value="COMPOSITE">COMPOSITE</option>'
            ;
         break;
      
      case "encoder_SDStandard":
         ret = ''
            +  '<option value="NTSC">NTSC</option>'
            +  '<option value="PAL">PAL</option>'
            ; 
         break;

      case "encoder_dropmode":
          ret = ''
             +  '<option value="OFF">STOP ENCODING</option>'
             +  '<option value="BARS_BLACK">BLACK</option>'
             +  '<option value="BARS">BARS</option>'
             +  '<option value="BARSTONES">BARS & TONES</option>'
             +  '<option value="BARSOVERLAY">BARS & SRV ID</option>'
             +  '<option value="BARSTONESOVERLAY">BARS, TONES & SRV. ID</option>'
             ; 
          break; 
         
      case "encoder_hSize"://(horizontal: 1920, 1280) (vertical: 720, 1080)
         switch(GetProductId())
            {
            case _PRODUCT.EN40.id:
            case _PRODUCT.EN41.id:
               ret +=  '<option value="720">720</option>';
               break;
               
            case _PRODUCT.MEDIAHUBHD.id:
            case _PRODUCT.EDJE5110.id:
               if((GetProductId()!=_PRODUCT.EDJE5110.id) && (GetProductId()!=_PRODUCT.EN40.id)&& (GetProductId()!=_PRODUCT.EN41.id))
                  {//HD options are NOT available for EDJE-5110 or EN40
                  
                  if((setting["sysd_fea_highdef"]===undefined)||(setting["sysd_fea_highdef"]))
                     { //Features command is not supported, or highDefinition is enabled
                     ret = ''
                        +  '<option value="1920">1920</option>'
                        +  '<option value="1440">1440</option>'
                        +  '<option value="1280">1280</option>'
                        ;
                     }
                  else
                     { //high definition feature is NOT enabled
                     ret = ''
                        +  '<option value="1920" disabled="true">1920</option>'
                        +  '<option value="1440" disabled="true">1440</option>'
                        +  '<option value="1280" disabled="true">1280</option>'
                     ;
                   
                     }
                  }
                  
               ret += '' 
                  +  '<option value="720">720</option>'
                  +  '<option value="704">704</option>'
                  +  '<option value="640">640</option>'
                  +  '<option value="544">544</option>'
                  +  '<option value="528">528</option>'
                  +  '<option value="480">480</option>'
                  +  '<option value="352">352</option>'
                  ;
               break;
            
            case _PRODUCT.MEDIAHUBHD_422.id:
            case _PRODUCT.EN80.id:
            case _PRODUCT.EN81.id:
            case _PRODUCT.EN20.id:
               if(GetProductId()==_PRODUCT.EN91.id)
                  {
                  ret =  '<option value="1">AUTO</option>';
                  }
               var optionDisabled = 'disabled="disabled"';
               if((setting["sysd_fea_highdef"]===undefined)||(setting["sysd_fea_highdef"]))
                  { //Features command is not supported, or highDefinition is enabled
                  optionDisabled = '';
                  }
               ret += ''
                  +  '<option ' + optionDisabled + ' value="1920">1920</option>'
                  +  '<option ' + optionDisabled + ' value="1440">1440</option>'
                  +  '<option ' + optionDisabled + ' value="1280">1280</option>'
                  ;
               if(GetProductId()==_PRODUCT.EN91.id)
                  {
                  ret += ''
                     + '<option ' + optionDisabled + ' value="960">960</option>'
                     + '<option ' + optionDisabled + ' value="848">848</option>'
                     ;
                  }
               ret += '<option value="720">720</option>';
               if(GetProductId()==_PRODUCT.EN91.id)
                  {
                  ret += ''
                     + '<option ' + optionDisabled + ' value="640">640</option>'
                     + '<option value="544">544</option>'
                     + '<option value="480">480</option>'
                     + '<option value="352">352</option>'
                     ;
                  }
               break;
               
            
             //From MID 5751 (For EN-91s):  Currently there is no was to detect the native input resolution. So it looks like the "Horizontal Size:" drop down list will need to be updated to list ALL possible resolutions.
//               Please update the list to with the following hsizes:
//               1920, 1440, 1280, 960, 848, 720, 640, 544, 480, 352   
               
            case _PRODUCT.EN91.id:   
               ret = [
                     '<option value="1">AUTO</option>',
                     '<option value="1920">1920</option>',
                     '<option value="1440">1440</option>',
                     '<option value="1280">1280</option>',
                     '<option value="960">960</option>',
                     '<option value="848">848</option>',
                     '<option value="720">720</option>',
                     '<option value="640">640</option>',
                     '<option value="544">544</option>',
                     '<option value="480">480</option>',
                     '<option value="352">352</option>'
                     ].join("");
               break;
            }
            break;
      
      case "encoder_vSize":
         switch(GetProductId())
            {
            case _PRODUCT.MEDIAHUBHD.id:
            case _PRODUCT.MEDIAHUBHD_422.id:
            case _PRODUCT.EN80.id:
            case _PRODUCT.EN81.id:
            case _PRODUCT.EN91.id:
            case _PRODUCT.EN20.id:
               if((setting["sysd_fea_highdef"]===undefined)||(setting["sysd_fea_highdef"]))
                  { //Features command is not supported, or highDefinition is enabled
                  ret = ''
                     +  '<option value="1080">1080</option>'
                     +  '<option value="720">720</option>'
                     ;
                  }
               else
                  {
                  ret = ''
                     +  '<option disabled="true" value="1080">1080</option>'
                     +  '<option disabled="true" value="720">720</option>'
                     ;
                  }
               ret+= '<option value="576">576</option>'
                  +  '<option value="480">480</option>'       
                  ;     
               break;
               
            case _PRODUCT.EN40.id:
            case _PRODUCT.EN41.id:
            case _PRODUCT.EDJE5110.id:
               ret+= '<option value="576">576</option>'
                  +  '<option value="480">480</option>'       
                  ;     
               break;
            }
         break;
      
      case "encoder_chromatype":
         ret = ''
            +  '<option value="420">420</option>'
            +  '<option value="422">422</option>'
            ; 
         break;
         
      case "encoder_vencode":
      
         ret = '<option value="H264">MPEG4 (H264)</option>';   
         if(SupportsCodecModeChange())
            {
            ret += '<option value="MPEG2">MPEG2</option>';
            }
         break;

      case "encoder_ecd":
         ret = ''
            +  '<option value="0">CABAC</option>'
            +  '<option value="1">CAVLC</option>'
            +  '<option value="2">AUTO</option>'
            ;
         break;
         
      case "encoder_aspectRatio":
         ret = ''
            +  '<option value="4X3">4x3</option>'
            +  '<option value="16X9">16x9</option>'
            +  '<option value="WSS">WSS</option>'
            ; 
         break;
      
      case "encoder_temporal":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="WEAK">WEAK</option>'
            +  '<option value="MEDIUM">MEDIUM</option>'
            +  '<option value="STRONG">STRONG</option>'
            +  '<option value="MAX">MAX</option>'
            ;
         break;
      
      case "encoder_spatial":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="WEAK">WEAK</option>'
            +  '<option value="MEDIUM">MEDIUM</option>'
            +  '<option value="MAX">MAX</option>'
            ;
         break;
      
      case "decoder_active":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="ON">CONF. DECODE</option>'
            +  '<option value="DVB">DVB-ASI</option>'  
            ;  
         break;
      
      case "display_displayTarget":
      case "decoder_displayTarget":
         if(!IsPlayerUnit())
            {
            ret = ''
               +  '<option value="1">NTSC</option>'
               +  '<option value="2">PAL (BG)</option>'
               +  '<option value="3">PALM</option>'
               +  '<option value="4">PALN</option>'
               +  '<option value="5">NTSCJ</option>'
               +  '<option value="7">1280x720p 50 fps</option>'
               +  '<option value="49">1280x720p 59.94 fps</option>'
               +  '<option value="8">1280x720p 60 fps</option>'
               +  '<option value="10">1920x1080i 50 fps</option>'
               +  '<option value="50">1920x1080i 59.94 fps</option>'
               ;
            }
         else
            {
            ret = ''
               +  '<option value="">   ---   Recommended   ---   </option>'
               +  '<option value="1">NTSC</option>'
               +  '<option value="2">PAL</option>'
               +  '<option value="3">PALM</option>'
               +  '<option value="4">PALN</option>'
               +  '<option value="5">NTSCJ</option>'
               +  '<option value="7">720p 50 fps</option>'
               +  '<option value="49">720p 59.94 fps</option>'
               +  '<option value="8">720p 60 fps</option>'
               +  '<option value="10">1080i 50 fps</option>'
               +  '<option value="50">1080i 59.94 fps</option>'
               +  '<option value="">   ---   Others   ---   </option>'
               +  '<option value="9">1080p 24 fps</option>'
               +  '<option value="52">1080p 23 fps</option>'
               +  '<option value="11">1080p 50 fps</option>'
               +  '<option value="51">1080p 59 fps</option>'
               +  '<option value="13">1080p 60 fps</option>'
               +  '<option value="12">1080i 60 fps</option>'
               +  '<option value="14">VESA 640  X 350 85Hz</option>'
               +  '<option value="15">VESA 640  X 400 85Hz</option>'
               +  '<option value="16">VESA 640  X 480 60Hz</option>'
               +  '<option value="17">VESA 640  X 480 72Hz</option>'
               +  '<option value="18">VESA 640  X 480 75Hz</option>'
               +  '<option value="19">VESA 640  X 480 85Hz</option>'
               +  '<option value="20">VESA 720  X 400 85Hz</option>'
               +  '<option value="21">VESA 800  X 600 56Hz</option>'
               +  '<option value="22">VESA 800  X 600 60Hz</option>'
               +  '<option value="23">VESA 800  X 600 72Hz</option>'
               +  '<option value="24">VESA 800  X 600 75Hz</option>'
               +  '<option value="25">VESA 800  X 600 85Hz</option>'
               +  '<option value="26">VESA 848  X 480 60Hz</option>'
               +  '<option value="27">VESA 1024  X 768 43Hz</option>'
               +  '<option value="28">VESA 1024  X 768 60Hz</option>'
               +  '<option value="29">VESA 1024  X 768 70Hz</option>'
               +  '<option value="30">VESA 1024  X 768 75Hz</option>'
               +  '<option value="31">VESA 1024  X 768 85Hz</option>'
               +  '<option value="32">VESA 1152  X 864 75Hz</option>'
               +  '<option value="33">VESA 1280  X 768 60Hz</option>'
               +  '<option value="34">VESA 1280  X 768 75Hz</option>'
               +  '<option value="35">VESA 1280  X 768 85Hz</option>'
               +  '<option value="36">VESA 1280  X 960 60Hz</option>'
               +  '<option value="37">VESA 1280  X 960 85Hz</option>'
               +  '<option value="38">VESA 1280  X 1024 60Hz</option>'
               +  '<option value="39">VESA 1280  X 1024 75Hz</option>'
               +  '<option value="40">VESA 1280  X 1024 85Hz</option>'
               +  '<option value="41">VESA 1360  X 768 60Hz</option>'
               +  '<option value="42">VESA 1400  X 1050 60Hz</option>'
               +  '<option value="43">VESA 1400  X 1050 75Hz</option>'
               +  '<option value="44">VESA 1400  X 1050 85Hz</option>'
               +  '<option value="45">VESA 1600  X 1200 60Hz</option>'
               +  '<option value="46">VESA 1920  X 1200 60Hz</option>'
               +  '<option value="47">XGA 1080i 50</option>'
               +  '<option value="48">XGA 1080i 60</option>'           
               ;
            }
            break;               
         
      case "encoder_gopType":
         ret = ''
            +  '<option value="OPEN">OPEN</option>'
            +  '<option value="CLOSED">CLOSED</option>'
            ;
         break;
   
      case "encoder_gopStructure":
         ret = ''
            +  '<option value="IBBP">IBBP</option>'
            +  '<option value="IBP">IBP</option>'
            +  '<option value="IP">IP</option>'
            +  '<option value="I">I</option>'
            ;
         break;
   
      case "encoder_gopSize":
      
         for( i=1; i<=30; i++)
            {
            ret += '<option value="' + i + '">' + i + '</option>';
            }
      
         break;
         
      case "dpiChMode":
      case "encoder_deblockFiltering":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="ON">ON</option>'
            ;
         break;
   
      case "encoder_fieldCodingStatus":
         ret = ''
            +  '<option value="FIELD">FIELD</option>'
            +  '<option value="FRAME">FRAME</option>'
            +  '<option value="AFF">ADAPTIVE</option>'
            ;
         break;
      
      case "barsTonesID_colors":
          ret = ''
             +     '<option value="BLACK">BLACK</option>'
             +     '<option value="BLUE">BLUE</option>'
             +     '<option value="RED">RED</option>'
             +     '<option value="MAGENTA">MAGENTA</option>'
             +     '<option value="GREEN">GREEN</option>'
             +     '<option value="CYAN">CYAN</option>'
             +     '<option value="YELLOW">YELLOW</option>'
             +     '<option value="WHITE">WHITE</option>'
             ;
          if(IsEncoderUnit())
             {
             ret += '<option value="FLASH">FLASH</option>';
             }
          break;   
         
      case "inventory_AudioTrack":
      case "streaming_audioTrackSelect":
      case "decoder_audioTrackSelect":
         ret = '';
         for( i=1; i<=_numAudioTracks; i++)
            {
            ret += '<option value="'+i+'">'+i+'</option>';
            }
      
         break;
      case "streaming_connector":
         ret = ''
            +  '<option value="ETHERNET">ETHERNET</option>'
            +  '<option value="GIGE">GIGE</option>'
            ;
         break;   

      case "display_blank":
         ret = ''
            +  '<option value="NOVIDEO">NO VIDEO</option>'
            +  '<option value="BLACK">BLACK</option>'
            +  '<option value="HOLD">HOLD</option>'
            ;  
         break;
         
      case "display_aspectRatio":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="AUTO">AUTO</option>'
            +  '<option value="4x3">4x3</option>'
            +  '<option value="16x9">16x9</option>'               
            ;
         break;
         
      case "db_playout_list":
         ret = ''
            +  '<option value="N/A">N/A</option>'
            ;
         break;

      case "streaming_dvbMode":            
      case "streaming_multicastMode":
      case "decoder_dvb":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="RECEIVE">RECEIVE</option>'
            ;
         break;
   
      case "cas_ecrMode":
         ret = ''
            +  '<option value="OFF">OFF</option>'
            +  '<option value="BISS_1">BISS_1</option>'
            +  '<option value="BISS_E_USER_ID_ONE">BISS_E_USER_ID_ONE</option>'
            +  '<option value="BISS_E_USER_ID_TWO">BISS_E_USER_ID_TWO</option>'
            ; 
         break;
      
      case "studio_controlInterface":
         ret = ''
            +  '<option value="NONE">NONE</option>'
            +  '<option value="RS422">RS422</option>'
            +  '<option value="RS422DEVICE">RS422DEVICE</option>'    
            ;   
         break;
                  
      case "studio_preRoll":
         
         for( i=0; i<10; i++)
            {
            ret += '<option value="' + i + '">' + i + '</option>';
            }
      
         break; 
      
      case "schDow":
         ret = ''
            +  '<option value="'+_SCHWILDCARD+'" >--</option>'
            +  '<option value="SU">Sun</option>'  
            +  '<option value="MO">Mon</option>'
            +  '<option value="TU">Tue</option>'
            +  '<option value="WE">Wed</option>'
            +  '<option value="TH">Thu</option>'
            +  '<option value="FR">Fri</option>'
            +  '<option value="SA">Sat</option>'
            ;
         break;
      case "schMonth":
         ret = ''
            +  '<option value="--" >-- </option>'
            +  '<option value="Jan">Jan</option>'  
            +  '<option value="Feb">Feb</option>'
            +  '<option value="Mar">Mar</option>'
            +  '<option value="Apr">Apr</option>'
            +  '<option value="May">May</option>'
            +  '<option value="Jun">Jun</option>'
            +  '<option value="Ju;">Jul</option>'
            +  '<option value="Aug">Aug</option>'
            +  '<option value="Sep">Sep</option>'
            +  '<option value="Oct">Oct</option>'
            +  '<option value="Nov">Nov</option>'
            +  '<option value="Dec">Dec</option>'
            ;
         break;
      
      case "schDay":
         ret = '<option value="--" >-- </option>';
         for(i=1; i<=_MAXDAYSINMONTH; i++)
            {//add one option for every day of the month
            ret +=   '<option value="' + i + '">' + i + '</option>';
            }
         break;
      
      case "schYear":
         ret = '<option value="--" >-- </option>';
         for( i=_MINYEAR; i<=_MAXYEAR; i++)
            {//add one option for every year allowed
            ret +=   '<option value="' + i + '">' + i + '</option>';
            }
         break;
      
      case "schHour":
         ret = '<option value="--" >-- </option>';
         for( i=0; i<=_MAXHOUR; i++)
            {//add one option for every Hour of the day
            ret +=   '<option value="' + i + '">' + i + '</option>';
            }
         break;
      
      case "schMinute":
         ret = '<option value="--" >-- </option>';
         for( i=0; i<=_MAXMINUTE; i++)
            {//add one option for every year allowed
            ret +=   '<option value="' + i + '">' + i + '</option>';
            }
         break;
      
      case "schEvtType":
         ret = '<option>--Select Event Type--</option>';
         
         for( i=0; i<_SCHSTREVENTTYPE.length; i++)
            {
            ret+= '<option value="' + i + '">'+ _SCHSTREVENTTYPE[i] + '</option>';   
            }
         break;
      case "demod_rfgain":
         ret = ''
         +  '<option value="0,0">0,0</option>'  
         +  '<option value="0,4.2">0,4.2</option>'
         +  '<option value="0,8.4">0,8.4</option>'
         +  '<option value="0,12.6">0,12.6</option>'
         +  '<option value="4,0">4,0</option>'
         +  '<option value="4,4.2">4,4.2</option>'
         +  '<option value="4,8.4">4,8.4</option>'
         +  '<option value="4,12.6">4,12.6</option>'
            ;
         
         break;
         
      case "demod_bbgain":
         ret = ''
            +  '<option value="0">0</option>'  
            +  '<option value="4.2">4.2</option>'
            +  '<option value="8.4">8.4</option>'
            +  '<option value="12.6">12.6</option>'
            ;
         break;
         
      case "demodulator_rollOff_ntc": //TODO: Replace magic values..  Check for option valid values
         ret = '';
         var swVer = parseFloat(setting["sysd_sup_sw_ver"]),
         boardId = setting["sysd_sup_id"],   abRegex = /NTC\/7044\/AB/, bbRegex = /NTC\/7044\/BB/;
         
         /*
          * From MID 6420:
          * Acceptance Criteria: I need to be able to choose 5%, 10% & 15% roll-off as options for 
          * the following Newtec demods with these firmware versions.
          * 
          * 7044.AB (fw: 1.35 and greater)
          * 7044.BB (fw: 2.30 and greater)
          */
         
         if(
            ((swVer>=1.35)&& abRegex.test(boardId)) ||  // 7044.AB (fw: 1.35 and greater)
            ((swVer>=2.3) && bbRegex.test(boardId))     // 7044.BB (fw: 2.30 and greater)
            )
            {
            ret += ''
               +  '<option value="5%">5%</option>'
               +  '<option value="10%">10%</option>' 
               +  '<option value="15%">15%</option>'
               ;
            }   
         /*
          * End of exception for MID 6420
          */
         
         
          ret += ''
             +  '<option value="20%">20%</option>'
             +  '<option value="25%">25%</option>' 
             +  '<option value="35%">35%</option>' 
             +  '<option value="AUTO">AUTO</option>'
             ;
          break;  
         
      case "demodulator_rollOff_adt": //TODO: Replace magic values..  Check for option valid values
         ret = ''
            +  '<option value="20%">20%</option>'
            +  '<option value="25%">25%</option>' 
            +  '<option value="35%">35%</option>' 
            ;
         break;  

     case "demodulator_frameType": //TODO: Replace magic values..  Check for option valid values
         ret = ''
            +  '<option value="NORMAL">NORMAL</option>'
            +  '<option value="SHORT">SHORT</option>'
            + '<option value="N/A" disabled="disabled">N/A</option>'
            +  '<option value="AUTO">AUTO</option>' 
            ;
         break; 

      case "modLoPresets":
         ret = ''
            +  '<option value="MANUAL_DIRECT">MANUAL(Normal)</option>'
            +  '<option value="MANUAL_INVERTED">MANUAL(Invert)</option>'
            +  '<optgroup label="Normal">'
            +     '<option value="C_4900">C: 4900</option>'
            +     '<option value="C_5290">C: 5290</option>'
            +     '<option value="C_5475">C: 5475</option>'
            +     '<option value="C_5750">C: 5750</option>'
            +     '<option value="C_5775">C: 5775</option>'
            +     '<option value="X_6950">X: 6950</option>'
            +     '<option value="X_7000">X: 7000</option>'
            +     '<option value="KU_12800">KU: 12800</option>'
            +     '<option value="KU_13050">KU: 13050</option>'
            +     '<option value="DBS_16350">DBS: 16350</option>'
            +     '<option value="DBS_16950">DBS: 16950</option>'
            +     '<option value="KA_28850">KA: 28850</option>'
            +     '<option value="KA_29000">KA: 29000</option>'
            +     '<option value="KA_29050">KA: 29050</option>'
            +  '</optgroup>'
            +  '<optgroup label="Invert">'
            +     '<option value="C_7300">C: 7300</option>'
            +     '<option value="C_7375">C: 7375</option>'
            +     '<option value="C_7600">C: 7600</option>'
            +     '<option value="C_7675">C: 7675</option>'
            +     '<option value="C_7875">C: 7875</option>'
            +     '<option value="C_8175">C: 8175</option>'
            +     '<option value="KU_15200">KU: 15200</option>'
            +     '<option value="KU_15450">KU: 15450</option>'
            +  '</optgroup>'
            ;
         
         break;
         
      case "localOscillatorPresets": //TODO: Replace magic values
         ret = ''
            + '<option value="C_5150">C: 5150</option>'
            + '<option value="KU_11300">KU: 11300</option>'
            + '<option value="KU_10750">KU: 10750</option>'
            + '<option value="KU_10600">KU: 10600</option>'
            + '<option value="KU_10000">KU: 10000</option>'
            + '<option value="KU_9750">KU: 9750</option>'
            + '<option value="KU_9600">KU: 9600</option>'
            + '<option value="C_MANUAL">C: MANUAL</option>'
            + '<option value="KU_MANUAL">KU: MANUAL</option>'
            ;
      break; 
         
      case "demodulator_pilot_ntc": //TODO: Replace magic values
          ret = ''
           + '<option value="AUTO">AUTO</option>' 
           + '<option value="ON">ON</option>'
           + '<option value="OFF">OFF</option>'
           + '<option value="N/A" disabled="disabled">N/A</option>'
           ;
          break;         
          
      case "demodulator_pilot_adt": //TODO: Replace magic values
          ret = ''
           + '<option value="ON">ON</option>'
           + '<option value="OFF">OFF</option>'
           + '<option value="N/A">N/A</option>'
           ;
          break;         
          
      case "demodulator_active": //TODO: Replace magic values
      case "demodulator_activeInput": //TODO: Replace magic values
          ret = ''
           + '<option value="YES">YES</option>'
           + '<option value="NO">NO</option>'
           ;
          break;

      case "demodulator_select": //TODO: Replace magic values
          ret = ''
           + '<option value="0">RF 1</option>'
           + '<option value="1">RF 2</option>'
           ;
          break;           

      case "demodulator_type": //TODO: Replace magic values
          ret = ''
           + '<option value="DVB-S">DVB-S</option>'
           + '<option value="DVB-S2">DVB-S2</option>'
           ;
          break; 
          
      case "demodulator_ccm": //TODO: Replace magic values
          ret = ''
           + '<option value="AUTO-CCM">AUTO-CCM</option>'
           + '<option value="CCM">CCM</option>'           
           ;
          break;    
          
      case "demodulator_mode": //TODO: Replace magic values
         if(HasNewtecDemod())
            {
               
            ret = ''
               +  '<option value="QPSK_1/2">QPSK_1/2</option>' 
               +  '<option value="QPSK_2/3">QPSK_2/3</option>'
               +  '<option value="QPSK_3/4">QPSK_3/4</option>' 
               +  '<option value="QPSK_5/6">QPSK_5/6</option>'
               +  '<option value="QPSK_6/7">QPSK_6/7</option>' 
               +  '<option value="QPSK_7/8">QPSK_7/8</option>'
               +  '<option value="QPSK_1/4">QPSK_1/4</option>'
               +  '<option value="QPSK_1/3">QPSK_1/3</option>' 
               +  '<option value="QPSK_2/5">QPSK_2/5</option>'
               +  '<option value="QPSK_3/5">QPSK_3/5</option>'
               +  '<option value="QPSK_4/5">QPSK_4/5</option>'
               +  '<option value="QPSK_8/9">QPSK_8/9</option>'
               +  '<option value="QPSK_9/10">QPSK_9/10</option>'
               +  '<option value="QPSK_AUTO">QPSK_AUTO</option>' 
               +  '<option value="8PSK_3/5">8PSK_3/5</option>'
               +  '<option value="8PSK_2/3">8PSK_2/3</option>'
               +  '<option value="8PSK_3/4">8PSK_3/4</option>'
               +  '<option value="8PSK_5/6">8PSK_5/6</option>'
               +  '<option value="8PSK_8/9">8PSK_8/9</option>'
               +  '<option value="8PSK_9/10">8PSK_9/10</option>'
               +  '<option value="8PSK_AUTO">8PSK_AUTO</option>'
               +  '<option value="16QAM_3/4">16QAM_3/4</option>'
               +  '<option value="16QAM_7/8">16QAM_7/8</option>'
               +  '<option value="16QAM_AUTO">16QAM_AUTO</option>'
               +  '<option value="16APSK_2/3">16APSK_2/3</option>'
               +  '<option value="16APSK_3/4">16APSK_3/4</option>'
               +  '<option value="16APSK_4/5">16APSK_4/5</option>'
               +  '<option value="16APSK_5/6">16APSK_5/6</option>'
               +  '<option value="16APSK_8/9">16APSK_8/9</option>'
               +  '<option value="16APSK_9/10">16APSK_9/10</option>'
               +  '<option value="32APSK_3/4">32APSK_3/4</option>'
               +  '<option value="32APSK_4/5">32APSK_4/5</option>'
               +  '<option value="32APSK_5/6">32APSK_5/6</option>'
               +  '<option value="32APSK_8/9">32APSK_8/9</option>'
               +  '<option value="32APSK_9/10">32APSK_9/10</option>'
               +  '<option value="AUTO" disabled="disabled">AUTO</option>'
               ;
            }
         else if (HasAdtecDemod())
            {
            ret = ''
               +  '<option value="QPSK_1/2">QPSK_1/2</option>' 
               +  '<option value="QPSK_3/5">QPSK_3/5</option>'
               +  '<option value="QPSK_2/3">QPSK_2/3</option>'
               +  '<option value="QPSK_3/4">QPSK_3/4</option>' 
               +  '<option value="QPSK_4/5">QPSK_4/5</option>'
               +  '<option value="QPSK_5/6">QPSK_5/6</option>'
               +  '<option value="QPSK_7/8">QPSK_7/8</option>'
               +  '<option value="QPSK_8/9">QPSK_8/9</option>'
               +  '<option value="QPSK_9/10">QPSK_9/10</option>'
               +  '<option value="8PSK_3/5">8PSK_3/5</option>'
               +  '<option value="8PSK_2/3">8PSK_2/3</option>'
               +  '<option value="8PSK_3/4">8PSK_3/4</option>'
               +  '<option value="8PSK_5/6">8PSK_5/6</option>'
               +  '<option value="8PSK_8/9">8PSK_8/9</option>'
               +  '<option value="8PSK_9/10">8PSK_9/10</option>'
               ;
            }
          break;            
          
      case "demodulator_ratePri": //TODO: Replace magic values
          ret = ''
           + '<option value="SYMBOL">SYMBOL</option>'
           + '<option value="INTERFACE">INTERFACE</option>'          
           ;
          break;     
   

      case "lnb_state": //TODO: Replace magic values
          ret = ''
           + '<option value="ON">ENABLE</option>'
           + '<option value="OFF">DISABLE</option>'
           ;
          break;            

      case "lnb_polarity": //TODO: Replace magic values
         if(HasNewtecDemod())
            {
            ret = ''
               + '<option value="OFF">OFF</option>'
               + '<option value="H">H 18v</option>'
               + '<option value="V">V 13v</option>'
               ;
            }
         else if(HasAdtecDemod())
            {
            ret = ''
               + '<option value="H">H 18v</option>'
               + '<option value="H+">H+ 19v</option>'
               + '<option value="V">V 13v</option>'
               + '<option value="V+">V+ 14v</option>'
               ;
            }
         break; 
         
      case "lnb_tone": //TODO: Replace magic values
         ret = '';
         if (HasNewtecDemod())
            {
            ret += '<option value="OFF">OFF</option>';
            }
         ret += ''
            + '<option value="0KHZ">0 KHz</option>'
            + '<option value="22KHZ">22 KHz</option>'
            ;
         break; 
         
      case "lband_transmit": //TODO: Replace magic values
          ret = ''
           + '<option value="0">DISABLED</option>'
           + '<option value="1">ENABLED</option>'
           ;
          break;  
          
       
      case "mod_type": //TODO: Replace magic values
          ret = ''
           + '<option value="' + _MODTYPE.DVB_S + '">DVB-S</option>'
           + '<option value="' + _MODTYPE.DVB_S2 + '">DVB-S2</option>'
           ;
          break; 
          
      case "mod_mode": //TODO: Replace magic values
          ret = ''
              +  '<option value="11">QPSK_1/2</option>' 
              +  '<option value="12">QPSK_2/3</option>'
              +  '<option value="13">QPSK_3/4</option>' 
              +  '<option value="15">QPSK_5/6</option>'
              +  '<option value="17">QPSK_7/8</option>'
              +  '<option value="21">QPSK_1/4</option>'
              +  '<option value="22">QPSK_1/3</option>' 
              +  '<option value="23">QPSK_2/5</option>'
              +  '<option value="24">QPSK_3/5</option>'
              +  '<option value="25">QPSK_4/5</option>'
              +  '<option value="26">QPSK_8/9</option>'
              +  '<option value="27">QPSK_9/10</option>'
              +  '<option value="81">8PSK_3/5</option>'
              +  '<option value="82">8PSK_2/3</option>'
              +  '<option value="83">8PSK_3/4</option>'
              +  '<option value="85">8PSK_5/6</option>'
              +  '<option value="88">8PSK_8/9</option>'
              +  '<option value="89">8PSK_9/10</option>'
              +  '<option value="63">16QAM_3/4</option>'
              +  '<option value="67">16QAM_7/8</option>'
              +  '<option value="42">16APSK_2/3</option>'
              +  '<option value="43">16APSK_3/4</option>'
              +  '<option value="44">16APSK_4/5</option>'
              +  '<option value="45">16APSK_5/6</option>'
              +  '<option value="48">16APSK_8/9</option>'
              +  '<option value="49">16APSK_9/10</option>'
              +  '<option value="53">32APSK_3/4</option>'
              +  '<option value="54">32APSK_4/5</option>'
              +  '<option value="55">32APSK_5/6</option>'
              +  '<option value="58">32APSK_8/9</option>'
              +  '<option value="59">32APSK_9/10</option>'
              ;
          break; 
        
      case "mod_spectrumInversion": //TODO: Replace magic values
          ret = ''
           + '<option value="' + _MOD_UPLINK_MODE.NORMAL + '">NORMAL</option>'
           + '<option value="' + _MOD_UPLINK_MODE.INVERTED + '">INVERT</option>'          
           ;
          break;  
          
      case "mod_RatePriority": //TODO: Replace magic values
          ret = ''
          + '<option value="1">SYMBOL</option>'
           + '<option value="0">INTERFACE</option>'          
           ;
          break;  
          
      case "mod_CarrierMode": //TODO: Replace magic values
          ret = ''
           + '<option value="0">PURE CARRIER</option>'
           + '<option value="1">ON</option>'          
           + '<option value="2">CLOCK/8</option>'  
           + '<option value="4">CLOCK/4</option>'  
           + '<option value="5">CLOCK/16</option>'  
           ;
          break;            

      case "mod_rollOff": //TODO: Replace magic values..  Check for option valid values
         ret = ''
            +  '<option value="3">20</option>'
            +  '<option value="2">25</option>' 
            +  '<option value="1">35</option>' 
            ;
         break;  
         
      case "mod_pilot": //TODO: Replace magic values
          ret = ''
           + '<option value="1">ON</option>'
           + '<option value="0">OFF</option>'
           ;
          break;  
          
      case "audio_sdiMatrixCh": //TODO: Replace magic values
          ret = ''
           + '<option value="-1">AUTO</option>'
           + '<option value="1">AUDIO 1</option>'
           + '<option value="3">AUDIO 2</option>'
           + '<option value="5">AUDIO 3</option>'
           + '<option value="7">AUDIO 4</option>'
           + '<option value="9">AUDIO 5</option>'
           + '<option value="11">AUDIO 6</option>'
           + '<option value="13">AUDIO 7</option>'
           + '<option value="15">AUDIO 8</option>'
           + '<option value="0">OFF</option>'
           ;
          break;            

      case "mod_fec_frameType": //TODO: Replace magic values
          ret = ''
           + '<option value="1">NORMAL</option>'
           + '<option value="0">SHORT</option>'
           ;
          break;        
    
      case "modcalc_usePilots":
         ret = ''
           
            ;
         break;
         
      case "guide_mpaaRating":
         ret = ''
            +  '<option value="'+ _MPAA_RATING.NOTRATED + '">'               + _MPAA_RATING_STR[_MPAA_RATING.NOTRATED]            + '</option>' 
            +  '<option value="' + _MPAA_RATING.G + '">'               + _MPAA_RATING_STR[_MPAA_RATING.G]            + '</option>'
            +  '<option value="' + _MPAA_RATING.PG + '">'+ _MPAA_RATING_STR[_MPAA_RATING.PG]+ '</option>'
            +  '<option value="' + _MPAA_RATING.PG13 + '">' + _MPAA_RATING_STR[_MPAA_RATING.PG13]+ '</option>'
            +  '<option value="' + _MPAA_RATING.R + '">' + _MPAA_RATING_STR[_MPAA_RATING.R]+ '</option>'
            +  '<option value="' + _MPAA_RATING.NC17 + '">' + _MPAA_RATING_STR[_MPAA_RATING.NC17]+ '</option>'
            ;
         break;
         
      case "guide_starRating":
         ret = ''
            +  '<option value="' + _STAR_RATING.NOTRATED + '">'+  _STAR_RATING_STR[_STAR_RATING.NOTRATED]+  '</option>'
            +  '<option value="' + _STAR_RATING.HALF + '">'+  _STAR_RATING_STR[_STAR_RATING.HALF]+  '</option>'
            +  '<option value="' + _STAR_RATING.ONE + '">'+  _STAR_RATING_STR[_STAR_RATING.ONE]+  '</option>'
            +  '<option value="' + _STAR_RATING.ONEPLUSHALF + '">'+  _STAR_RATING_STR[_STAR_RATING.ONEPLUSHALF]+  '</option>'
            +  '<option value="' + _STAR_RATING.TWO + '">'+  _STAR_RATING_STR[_STAR_RATING.TWO]+  '</option>'
            +  '<option value="' + _STAR_RATING.TWOPLUSHALF + '">'+  _STAR_RATING_STR[_STAR_RATING.TWOPLUSHALF]+  '</option>'
            +  '<option value="' + _STAR_RATING.THREE + '">'+  _STAR_RATING_STR[_STAR_RATING.THREE]+  '</option>'
            +  '<option value="' + _STAR_RATING.THREEPLUSHALF + '">'+  _STAR_RATING_STR[_STAR_RATING.THREEPLUSHALF]+  '</option>'
            +  '<option value="' + _STAR_RATING.FOUR + '">'+  _STAR_RATING_STR[_STAR_RATING.FOUR]+  '</option>'
            +  '<option value="' + _STAR_RATING.FOURPLUSHALF + '">'+  _STAR_RATING_STR[_STAR_RATING.FOURPLUSHALF]+  '</option>'
            +  '<option value="' + _STAR_RATING.FIVE + '">'+  _STAR_RATING_STR[_STAR_RATING.FIVE]+  '</option>'
            ;
         
         break;
      
      case "guide_slvContent":
         ret = ''
            +  '<option value="' + _SLV_CONTENT.UNKNOWN + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.UNKNOWN]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.NONE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.NONE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.SEX + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.SEX]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.LANGUAGE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.LANGUAGE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.VIOLENCE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.VIOLENCE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.SEXLANGUAGE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.SEXLANGUAGE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.SEXVIOLENCE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.SEXVIOLENCE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.LANGUAGEVIOLENCE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.LANGUAGEVIOLENCE]+  '</option>'
            +  '<option value="' + _SLV_CONTENT.SEXLANGUAGEVIOLENCE + '">'+  _SLV_CONTENT_STR[_SLV_CONTENT.SEXLANGUAGEVIOLENCE]+  '</option>'
            ;
      
         break;
      
      case "guide_cc":
         ret = '';
         for( i=0; i<_CLOSED_CAPTION_STR.length; i++)
            {
            ret += '<option value="' + i + '">' + _CLOSED_CAPTION_STR[i] + '</option>';
            }  
            
         break;
      
      case "guide_stereo":
         ret = '';
         
         for( i=0; i<_STEREO_STR.length; i++)
            {
            ret += '<option value="' + i + '">' + _STEREO_STR[i] + '</option>';
            }  
            
         break;
      
      case "guide_releaseYear":
         ret = '<option value="-1">--</option>';
         for( i=_MIN_RELEASE_YEAR; i<=_MAX_RELEASE_YEAR; i++)
            {
            ret+= '<option value="' + i + '">' + i + '</option>';  
            }
         break;
      
      case "rdGenMode":
         ret = ''
            +  '<option value="0">OFF</option>'
            +  '<option value="1">SLAVE</option>'
            +  '<option value="2">REMOTE</option>'
            ;
         break;
         
      case "rdGenCvbs":
         ret = ''
            +  '<option value="0">VIDEO</option>'
            +  '<option value="1">SYNC</option>'
            ;
         break;
         
      case "rdGenPixP":
         ret = '';
         for(i=0; i<=_MAX_RD_GEN_PIX_PHASE; i++)
            {
            ret+= '<option value="' + i + '">' + i + "</option>";
            }
         break;
      
      case "rdVbiDc":
         ret = ''
            +  '<option value="0">OFF</option>'
            +  '<option value="15">ON</option>'
            ; 
         break;
      case "rdVbiLineNumbers":
         ret = '<option value="0">DISABLED</option>';
         for(i=_MIN_VBI_LINE_NUMBER; i<=_MAX_VBI_LINE_NUMBER; i++)
            {
            ret += '<option value="' + i + '">' + i + '</option>';
            }
         break;
      case "rdSdiTeletextNumbers":
         ret = '<option value="0">DISABLED</option>';
         for(i=_MIN_SDI_TLTXT_LINE_NUMBER; i<=_MAX_SDI_TLTXT_LINE_NUMBER; i++)
            {
            ret += '<option value="' + i + '">' + i + '</option>';
            }
         break;
         
      case "rdVidoScaling":
         ret = ''
            +  '<option value="0">DEFAULT</option>'
            +  '<option value="1">NTSC</option>'
            +  '<option value="2">PAL</option>'
            ;
         break;
         
      case "rdVidoFaultMode":
         ret = ''
            +  '<option value="0">480I59.94</option>'
            +  '<option value="1">576I50</option>'
            +  '<option value="2">720P59.94</option>'
            +  '<option value="3">720P50</option>'
            +  '<option value="4">1080I59.94</option>'
            +  '<option value="5">1080I50</option>'
            ;
         break;
      
         
      case "rdVidoTxtSize":
         ret = ''
            +  '<option value="0">1X</option>'
            +  '<option value="1">2X</option>'
            +  '<option value="2">4X</option>'
            ;
         break;
      
      case "rdOsdOutput":
         ret = ''
            +  '<option value="0">ALL OFF</option>'
            +  '<option value="1">SDI</option>'
            +  '<option value="2">SDI ALT</option>'
            +  '<option value="3">SDI & SDIALT</option>'
            ;
         break;
         
      case "rdOsdSvcLines":
         ret = ''
            +  '<option value="0">NONE</option>'
            +  '<option value="1">Service Name</option>'
            +  '<option value="2">Service Provider</option>'
            +  '<option value="3">Input</option>'
            +  '<option value="4">TMR</option>'
            ;
         break;
         
      case "rdOsdSvcBlink":
         ret = ''
            +  '<option value="0">NO BLINK</option>'
            +  '<option value="1">Line 1 only</option>'
            +  '<option value="2">Line 2 only</option>'
            +  '<option value="4">Line 3 only</option>'
            +  '<option value="8">Line 4 only</option>'
            +  '<option value="3">Lines 1 & 2</option>'
            +  '<option value="5">Lines 1 & 3</option>'
            +  '<option value="9">Lines 1 & 4</option>'
            +  '<option value="6">Lines 2 & 3</option>'
            +  '<option value="10">Lines 2 & 4</option>'
            +  '<option value="12">Lines 3 & 4</option>'
            +  '<option value="7">Lines 1, 2 & 3</option>'
            +  '<option value="11">Lines 1, 2 & 4</option>'
            +  '<option value="13">Lines 1, 3 & 4</option>'
            +  '<option value="14">Lines 2, 3 & 4</option>'
            +  '<option value="15">All Lines Blink</option>'
            ;         
         break;
         
      case "rdOsdTxtFormat":
         ret = ''
            +  '<option value="0">NO CHAR</option>'
            +  '<option value="1">WHITE CHAR/NO OUTLINE</option>'
            +  '<option value="2">BLACK OUTLINE ONLY</option>'
            +  '<option value="3">WHITE CHAR/BLACK OUTLINE</option>'
            +  '<option value="4">WHITE CHAR/BLACK BACKGROUND</option>'
            +  '<option value="5">REVERSED VIDEO</option>'
            +  '<option value="6">WHITE CHAR OUTLINE</option>'
            +  '<option value="7">REVERSED VIDEO/BLACK OUTLINE</option>'
            ;
         break;
      
         
      case "rdCaptionsCvbs":
         ret = ''
            + '<option value="0">DISABLED</option>'
            + '<option value="21">21</option>'
            ;
         break;
      case "rdCaptionsTeletext":
         ret = ''
            + '<option value="0">DISABLED</option>'
            + '<option value="22">22</option>'
            ;
         break;
         
      case "dpiCcmsFormat": 
         ret = ''
            +  '<option value="novar">NOVAR</option>'
            +  '<option value="20/20">20/20</option>'
            +  '<option value="raw">RAW</option>'
            +  '<option value="left">LEFT</option>'
            +  '<option value="nonzero">NONZERO</option>'
            ;
         break;
      case "dpiNetsetMode": 
         ret = ''
            +  '<option value="INACTIVE">INACTIVE</option>'
            +  '<option value="INSERTNET">INSERTNET</option>'
            ;
         break;
      case "dpiNetsetType":              
         ret = ''
            +  '<option value="DTMF_TONE">DTMF_TONE</option>'
            +  '<option value="GPI">GPI</option>'
            +  '<option value="SCHED_TIME">SCHED_TIME</option>'
            +  '<option value="SCTE35">SCTE35</option>'
            ;
         break;
      case "dpiNetsetEndBy":             
         ret = ''
            +  '<option value="SPOT">SPOT</option>' 
            +  '<option value="SPOTAVAIL">SPOTAVAIL</option>'
            ;
         break;
         
      case "rdTcSource":
         ret = ''
            +  '<option value="0">PES</option>' 
            +  '<option value="1">VIDEO</option>'
            ;
         break;
         
      case "rdTcSdiOut":
      case "rdTcSdiAltOut":
         ret = ''
            +  '<option value="0">PASS</option>' 
            +  '<option value="1">LTC</option>'
            +  '<option value="2">VITC</option>' 
            +  '<option value="3">BOTH</option>'
            ;
         break;
         
      case "rdVidoVideoDrop":
         ret = [
            '<option value="--">--</option>',
            '<option value="STOP">STOP DECODING</option>', 
            '<option value="BLACK">BLACK</option>',
            '<option value="BARS">BARS</option>',
            '<option value="BARS_TONES">BARS & TONES</option>',
            '<option value="BARS_TONES_ID">BARS, TONES & SRV ID</option>'
            ].join("");
         break;
         
      case "modRefClk":
         ret = ''
            +  '<option value="0">OFF</option>' 
            +  '<option value="1">INTERNAL</option>'
            +  '<option value="2">EXTERNAL</option>'
            ;
         break;
      case "modRefClkComb":
         ret = ''
            +  '<option value="0">UNCOMBINED</option>'
            +  '<option value="1">COMBINED</option>'
            ;
         break;
         
      case "pmtLevel":
         ret = ''
            +  '<option value="--">--</option>'
            +  '<option value="2">0</option>'
            +  '<option value="3">1</option>'
            +  '<option value="4">2</option>'
            +  '<option value="5">3</option>'
            +  '<option value="6">4</option>'
            +  '<option value="7">5</option>'
            +  '<option value="8">6</option>'
            ;
         break;
      
      case "qamVbiCc":
         ret = 
            [
            '<option value="0">OFF</option>',
            '<option value="1">ATSC</option>',
            '<option value="2">DIVICOM</option>',
            '<option value="3">LINEAR</option>',
            '<option value="4">DVS157</option>',
            '<option value="5">ATSC CONVERT</option>',
            '<option value="6">ATSC 708</option>'
            ].join("");
         break;
         
      case "qamVbiSource":
         ret = 
            [
            '<option value="0">COMPOSITE</option>',
//            '<option value="1">INVALID</option>'
            '<option value="2">SDI</option>'
            ].join("");
         break;
         
      case "qvb_ttxt_ptx_mode":
            ret = 
               [
               '<option value="0">OFF</option>',
               '<option value="1">WAVEFORM</option>',
               '<option value="2">OP47</option>'
               ].join("");
         break;
         
      case "cas_ecrOnOff":
         ret = 
            [
            '<option value="0">OFF</option>',
            '<option value="1">ON</option>'
            ].join("");
         break;
         
      case "RdAudioDolbyDigitalMode":
         ret = 
            [
            '<option value="," disabled="disabled">--</option>',
            '<option value="0">COMPRESSED</option>',
            '<option value="2">STEREO</option>'
            ].join("");
         break;
         
      default:
         LogMyles("ERROR: Unknown id for set of options. None retrieved");
         break;
      }
      
   return ret;
      
   };/*****************************************************************************
 * @file
 * @author  Original:      German Escallon
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file handles the system tab.
 *****************************************************************************/ 

/****************************************************************************************************
 *                                  SYSTEM TAB Global Constants.
 *
 * NOTE:  const Keyword is not supported by Internet Explorer. Thus var is used instead.  
 * Treat these variables as #define's (in C/C++ code terms)and (even though its possible)  DO NOT 
 * re-assign any value to them at run time.                                            
****************************************************************************************************/
var 
   _CAL_TITLE =              "Choose a Date:",
   _MINCALDATE =             "1/1/1900",
   _MAXCALDATE =             "12/31/2099",
   _BOARD_NAME_SLOT =         2
   ;

/****************************************************************************************************
                                  SYSTEM TAB Global Variables
****************************************************************************************************/
var 
   _calendarControl, //YUI calendar object
   _calendarVisible, //boolean that identifies visibility state of calendar.
   _sysRebootingStarted,
   _resetModalPanel = null,
   _systemChanged = []
   
   ;
var  

/*
* Displays the form on the system tab
*/
RenderSystem = function()
   {
   LoadSystem();
   var systemHTML = ''
      
      //action buttons
      + '<br/><br/>'
      + '<form id="systemForm" >'
      + '<a onclick="return ValidateSystemForm(document.getElementById(&quot;systemForm&quot;));" > '
      
      // submit form
      + '  <img src="/images/apply.gif" />'
      + '</a>'
      + '&nbsp;&nbsp;&nbsp;'
      + '<a onclick="return LoadSystem();"> '
      
      // reloads tab
      + '  <img src="/images/cancel.gif" />'
      + '</a>'
      
      //   Uptime
      + '<div style="padding-left:330px;font-size:12px;"><b>Uptime:&nbsp;<img id="uptHint" onclick="ShowHelp(&quot;hlp_upt&quot;, this);" src="/images/hints.gif"/>'
      + '&nbsp;</b><span id="uptimeText" ></span></div>'
      + '<table width="100%">'

      + '<tr><td>'
      + '<table class="general">'

      // Hidden panel to Device Reset.
      + '<tr><td><div id="resetPanelDiv"></div><br/>'

      // Device Name
      + '<tr><td>Device Name: <img id="namHint" onclick="ShowHelp(&quot;hlp_nam&quot;, this);" src="/images/hints.gif"/></td>'
      + '<td><input onchange="_systemChanged[&quot;name&quot;]=true;" name="name" id="nameTextField" type="text" size="20" /></td>'
      
      // Power Reset Button
      + '<td></td><td align="right"> <img src="/images/reset.gif" onclick="return ShowResetWarningPanel();" /></td>'
      
      + '</tr>'
      // Horizontal Rule
      + '<tr><td colspan="4" style="width:auto;"><hr width="100%"></td></tr>'
      
      // Gateway Address
      + '<tr><td>Gateway Address: <img id="gipHint" onclick="ShowHelp(&quot;hlp_gip&quot;, this);"src="/images/hints.gif"/></td>'
      + '<td><input onselect = "return OnSystemFieldSelect(this)"'
      + 'onchange = "_systemChanged[&quot;gip&quot;]=true; OnSystemFieldChange(this)" '
      + 'name="gatewayAddress" id="gatewayAddressTextField" type="text" size="20" /></td>'
      ;
   
   if (SupportsNameserver())
      {
      // Nameserver IP
      systemHTML += ''
         +  '<td>Nameserver IP: <img onclick="ShowHelp(&quot;hlp_nsv&quot;, this);"src="/images/hints.gif"/></td>'
         + '<td><input id="nameserverTextfield" size="20" onchange="_systemChanged[&quot;ns&quot;] = true;"></input></td>'
         ;
      }
   else
      {
      systemHTML += '<td/><td/>';
      }

   systemHTML += ''
      + '</tr>'
      + '</table>'
      + '</td></tr>'
      + '<tr><td >'
      + '<table>'
      + '<tr>'
      
      // Eth0 Table
      + '<td colspan="2">'
      + '<table class="general">'
      + '<tr>'
      + '<td colspan="2" align="left" style="width:auto;"><b>Ethernet Port (eth0)</b> <hr width="100%"/></td>'
      + '</tr>'
      + '<tr>'
      + '<td  colspan="2" align="left">'
      
      // DHCP0
      + '<input onclick="return OnDHCPChange(this)" name="dhcpEth0" onchange="_systemChanged[&quot;dhcp0&quot;]=true;" '
      + 'type="checkbox" id="dhcpEth0CheckBox"  />DHCP : <img id="dhcHint" onclick="ShowHelp(&quot;hlp_dhc&quot;, this);" src="/images/hints.gif"/></td>'
      + '</tr>'
      + '<tr>'
      
      // Ethernet Address 0
      + '<td>Ethernet Address: <img id="ipa0Hint" onclick="ShowHelp(&quot;hlp_ipa0&quot;, this);" src="/images/hints.gif"/></td><td>'
      + '<input name="ethernetAddress" id="ethernetAddressTextField" '
      + 'onselect = "return OnSystemFieldSelect(this)" '
      + 'onchange="_systemChanged[&quot;ipa0&quot;]=true; OnSystemFieldChange(this)" type="text" size="20"/></td>'
      + '</tr>'
      + '<tr>'
      
      // Subnet Mask Eth0
      + '<td>Subnet Mask: <img id="ipmHint" onclick="ShowHelp(&quot;hlp_ipm&quot;, this);" src="/images/hints.gif"/></td><td>'
      + '<input name="subnetMaskEth0" id="subnetMaskEth0TextField" '
      + 'onselect="return OnSystemFieldSelect(this) " '
      + 'onchange="_systemChanged[&quot;mask0&quot;]=true; OnSystemFieldChange(this) " '
      + 'type="text" size="20"/></td>' 
      + '</tr>' 
      
      // Empty line to match GigE if exists
      + '<tr><td colspan="2">&nbsp;</td></tr>'
      + '</table>'
      + '</td>'
      
      // Eth1 Table
      + '<td colspan="2">'
      ;
   // eth1 settings are not available for signedge or edge-4111
   if ((GetProductId()!= _PRODUCT.SIGNEDJE.id) && (GetProductId()!= _PRODUCT.EDJE4111.id)) {

      systemHTML += ''
            + '<table class="general" id="eth1Table">'
            + '<tr>'
            + '<td colspan="2" align="left" style="width:auto;"><b>GigE Port (eth1)</b> <hr width="100%"/></td>'
            + '</tr>'
            + '<tr>'
            + '<td  colspan="2" align="left">'
            
            // DHCP1
            + '<input onclick="return OnDHCPChange(this)" name="dhcpEth1" onchange="_systemChanged[&quot;dhcp1&quot;]=true;" '
            + 'type="checkbox" id="dhcpEth1CheckBox"  />DHCP : <img id="dhc1Hint" onclick="ShowHelp(&quot;hlp_dhc1&quot;, this);" src="/images/hints.gif"/></td>'
            + '</tr>'
            + '<tr>'
            
            // GigE Address Eth1
            + '<td>GigE Address: <img id="ipa1Hint" onclick="ShowHelp(&quot;hlp_ipa1&quot;, this);" src="/images/hints.gif"/></td><td>'
            + '<input name="gigEAddress" id="gigEAddressTextField" '
            + 'onselect = "return OnSystemFieldSelect(this)" '
            + 'onchange="_systemChanged[&quot;ipa1&quot;]=true; OnSystemFieldChange(this)" type="text" size="20"/></td>'
            + '</tr>'
            + '<tr>'
            
            // Subnet Mask Eth1
            + '<td>Subnet Mask: <img id="ipmHint" onclick="ShowHelp(&quot;hlp_ipm&quot;, this);" src="/images/hints.gif"/></td><td>'
            + '<input name="subnetMaskEth1" id="subnetMaskEth1TextField" '
            + 'onselect="return OnSystemFieldSelect(this) " '
            + 'onchange="_systemChanged[&quot;mask1&quot;]=true; OnSystemFieldChange(this); " '
            + 'type="text" size="20"/></td>' 
            + '</tr>'
            + '<tr>'
            ;
            if ((GetProductId()== _PRODUCT.RD60.id) || (IsQamUnit()) || (GetProductId() == _PRODUCT.DTA.id)) {
                systemHTML += '' 
                + '<td></td><td></td>'
                ;
            } else {
                systemHTML += '' 
            // GbE Management Eth 1
                + '<td>GigE Management: <img id="gbeHint" onclick="ShowHelp(&quot;hlp_gbe&quot;, this);" src="/images/hints.gif"/></td><td>'
                + '<select onchange="_systemChanged[&quot;gbe&quot;]=true;" id="gbeManagementSelect">'
                   + GetSelectOptions("system_gbe")
                + '</select></td>'
                ;
            }
            systemHTML += '' 
            + '</tr>'
      + '</table>'
      ;
   }

   systemHTML += ''
         + '</td>'
         + '</tr>'
         + '</table>'
         + '</td></tr>'
         + '<tr><td>'
         + '<table class="general">'
         + '<tr>'
         + '</tr>'

         // Horizontal Rule
         + '<tr><td colspan="4" style="width:auto;"><hr width="100%"></td></tr>'
         + '<tr>'
         
         // NTP Address
         + '<td>NTP Address: <img id="nipHint" onclick="ShowHelp(&quot;hlp_nip&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;ntp&quot;]=true;" name="ntpAddress" id="ntpAddressTextField" type="text" size="20" /></td>'
         
         // Time Zone
         + '<td>Time Zone: <img id="tizHint" onclick="ShowHelp(&quot;hlp_tiz&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;timezone&quot;]=true;" name="timeZone" id="timeZoneTextField" type="text" size="20" /></td>'
         + '</tr>'
         + '<tr>'
         
         // Date
         + '<td>Date: <img id="timHint" onclick="ShowHelp(&quot;hlp_tim&quot;, this);" src="/images/hints.gif"/> '
         + '<img align="middle" id="calendarIcon" src="/images/calico.png" '
         + 'onmouseover="this.style.cursor=&quot;pointer&quot;;" '
         + 'onmouseout="this.style.cursor=&quot;default&quot;;" '
         + '/></td><td>'
         + '<input name="date" onchange="_systemChanged[&quot;time&quot;]=true;" id="dateTextField" '
         + 'type="text" size="20" /></td>'
         
         //Time
         + '<td>Time: <img id="timHint" onclick="ShowHelp(&quot;hlp_tim&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;time&quot;]=true;" name="time" id="timeTextField" type="text" size="20" /></td>'
         + '</tr>'
         + '</table>'
         + '</td></tr>'
         
         + '<tr><td>'
         
         ;
   
   if(SnmpSupported())
      {
      systemHTML += ''
         + '<table class="general">'
         // Horizontal Rule
         + '<tr><td colspan="4" style="width:auto;"><hr width="100%"></td></tr>'
         + '<tr>'
         
         // SNMP
         + '<td>SNMP: <img id="snmpHint" onclick="ShowHelp(&quot;hlp_snmp&quot;, this);" src="/images/hints.gif"/></td><td>'
         +  '<select onchange="_systemChanged[&quot;snmp&quot;]=true;" id="snmpSelect">' 
                     + GetSelectOptions("system_snmp")  
            +  '</select>'
            + '</td>'         
         
         // Blank
         + '<td></td><td></td>'
         + '</tr>'
         + '<tr>'
         
         // SNMP VAR 1 
         + '<td>Read Only Password: <img id="ropHint" onclick="ShowHelp(&quot;hlp_snmp_rop&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;snmp_ropw&quot;]=true;" name="snmp_ROPW" id="snmpROPWTextField" type="password" size="20" /></td>'
         
         // SNMP VAR 2
         + '<td>Read-Write Password: <img id="rwpHint" onclick="ShowHelp(&quot;hlp_snmp_rwp&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;snmp_rwpw&quot;]=true;" name="snmp_RWPW" id="snmpRWPWTextField" type="password" size="20" /></td>'
         + '</tr>'
         + '<tr>'
         
         // SNMP TRAP
         + '<td>Trap Community: <img id="trapComHint" onclick="ShowHelp(&quot;hlp_trap_com&quot;, this);" src="/images/hints.gif"/></td><td>'
         + '<input onchange="_systemChanged[&quot;snmp_trap&quot;]=true;" name="snmp_trap" id="snmpTRPTextField" type="text" size="20" /></td>'
         ;
      if(!IsQamUnit()) //NOTE GE 10/26/2010:  This functionality is not available in the TIGER-Branch.  Please remove this condition once it is supported.
         {
         // SNMP TRAPSINK
         systemHTML += ''
            + '<td>Trap Sink: <img id="trapSinkHint" onclick="ShowHelp(&quot;hlp_trap_sink&quot;, this);" src="/images/hints.gif"/></td><td>'
            + '<input onchange="_systemChanged[&quot;snmp_sink&quot;]=true;" name="snmp_sink" id="snmpPRNMTextField" type="text" size="20" /></td>'
            ;
         }
      else{ systemHTML += '<td></td>&nbsp;<td>&nbsp;</td>';}
      
      systemHTML += ''
         + '</tr>'
         + '</table>'
         ;
      }
   
   systemHTML += ''
         + '</td></tr>'
         + '</table>'
         
      
         // action buttons
         + '<br/><br/>'
         + '<a onclick="return ValidateSystemForm(document.getElementById(&quot;systemForm&quot;));" > '
         
         // submits form
         + '  <img src="/images/apply.gif" />' 
         + '</a>'
         + '&nbsp;&nbsp;&nbsp;' 
         + '<a onclick="return LoadSystem();"> '
         
         // reloads tab
         + '  <img src="/images/cancel.gif" />' 
         + '</a>' 
         + '<br/><br/>'
         + '</form>' 
         + '<div id="calendarContainer" style="bottom: 265px"/>'
         ;
  

   $("main_div").innerHTML = systemHTML;
   },

InitRebootPanel = function()
   {
// Sets the visible parameters cued by the OnWarning function
   var resetPanelConf = {
      width :"470px",
      height :"175px",
      modal :true,
      visible :false,
      autofillheight :"body",
      close :false,
      draggable :false,
      context : [ "namHint", // element to be aligned with
            "tl", // align topleft of panel
            "tr" // with topright of anchor
      ]
   };
   _resetModalPanel = new YAHOO.widget.Panel("resetPanelDiv", resetPanelConf);

   var panelBody = ''

         + '  <center><table class="hiddenPanel">'
         + '  <tr>'
         + '  <td style="background-color:#f4f4f4;border:0px;padding:0px;margins:0px;">'
         + '  <div id="warning"><img src="/images/warning.gif"/></div> You are about to power cycle your device.'
         + '    All encoding will stop and you will not be able to communicate with the device while it resets. (45 secs.) Are you sure this is what you want to do?</div>'
         + '  <br /><br />'
         + '  <center><img src="/images/interruptNOW.gif" onclick="SubmitReset();"/>'
         + '  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'
         + '  <img src="/images/cancel.gif" onClick="HideResetWarningPanel();" /></center></td>'
         + '  </tr>' 
         + '  </table><center>'
         ;

   _resetModalPanel.setHeader("<center><b>!! WARNING !!</b></center>");
   _resetModalPanel.setBody(panelBody);
   _resetModalPanel.render();
   
   },
   
LoadSystem = function()
   {
   ResetSystemChangedFlags();
   _yuiEvent.onAvailable("resetPanelDiv", InitRebootPanel, null, false, true);
   
   
   var query = ''
      +  '&q=SYSD+NA' //name and hostname for networking purposes
      +  '&q=SYSD+DHC+eth0'
      +  '&q=SYSD+IPA+eth0'
      +  '&q=SYSD+IPM+eth0'
      +  '&q=SYSD+GIP'
      +  '&q=SYSD+NIP'
      +  '&q=SYSD+UPT'
      +  '&q=SYSD+TIM'
      +  '&q=SYSD+TIZ' 
      +  '&q=SYSD+SNMP'
      +  '&q=SYSD+SNMPVAR'
      ;
   
   if (SupportsNameserver())
      {
      query += '&q=SYSD+NS';
      }

//   if(IsEncoderUnit())
//      {
//      _numPnpBoards = 0; //reset num of pnp boards
//      query+= '&q=SYSD+BI';
//      }   
      
   if((GetProductId()!=_PRODUCT.SIGNEDJE.id)&&(GetProductId()!=_PRODUCT.EDJE4111.id)) //eth1 settings are not available for signedge or edge-4111
      {
           
      query += ''
         +  '&q=SYSD+DHC+eth1'
         +  '&q=SYSD+IPA+eth1'
         +  '&q=SYSD+IPM+eth1'
         ;
      }
   if((GetProductId()!= _PRODUCT.RD60.id) && (!IsQamUnit()) && (GetProductId() != _PRODUCT.DTA.id))
   {
        
   query += ''
      +  '&q=SYSD+GBM'
      ;
   }      

   var XHRsuccess = function(o)
      {
   
      if(ParseResponse(o))
         {
         if (SupportsNameserver())
            {
            $("nameserverTextfield").value = setting["sysd_ns"];
            }
         $("nameTextField").value = setting["sysd_na"];
         $("ethernetAddressTextField").value = setting["sysd_ipa_eth0"]; 
         $("subnetMaskEth0TextField").value = setting["sysd_ipm_eth0"]; 
         $("gatewayAddressTextField").value = setting["sysd_gip"];
         $("ntpAddressTextField").value = setting["sysd_nip"] ;
         $("dateTextField").value = setting["sysd_tim_date"] ;
         $("timeTextField").value =  setting["sysd_tim_time"];
         $("timeZoneTextField").value = setting["sysd_tiz"];
         $("uptimeText").innerHTML = setting["sysd_upt"];
         
         if(SnmpSupported())
            {
            $("snmpSelect").value = setting["sysd_snmp"];         
            $("snmpROPWTextField").value = setting["sysd_snmpvar_rocommunity"];  
            $("snmpRWPWTextField").value = setting["sysd_snmpvar_rwcommunity"];
            $("snmpTRPTextField").value = setting["sysd_snmpvar_trapCommunity"];
            if(!IsQamUnit()){$("snmpPRNMTextField").value = setting["sysd_snmpvar_trapSink"];}   //NOTE GE 10/26/2010:  This functionality is not available in the TIGER-Branch.  Please remove this condition once it is supported.         
            }          
         
         if(setting["sysd_dhc_eth0"]=="ON") 
            {
            $("dhcpEth0CheckBox").checked = true;
            DisableEthFields("eth0");
            }
         else
            {
            $("dhcpEth0CheckBox").checked = false;
            EnableEthFields("eth0");
            }
         
         if((GetProductId()!=_PRODUCT.SIGNEDJE.id)&&(GetProductId()!=_PRODUCT.EDJE4111.id)) //eth1 settings are not available for signedge or edge-4111
            {
            $("gigEAddressTextField").value = setting["sysd_ipa_eth1"];
            $("subnetMaskEth1TextField").value = setting["sysd_ipm_eth1"];
            if((GetProductId()!= _PRODUCT.RD60.id) && (!IsQamUnit()) && (GetProductId() != _PRODUCT.DTA.id))
               {
               $("gbeManagementSelect").value = setting["sysd_gbm"];
               }
            if(setting["sysd_dhc_eth1"]=="ON") 
               {
               $("dhcpEth1CheckBox").checked = true;
               DisableEthFields("eth1");
               }
            else
               {
               $("dhcpEth1CheckBox").checked = false;
               EnableEthFields("eth1");
               }
            }
         
         
         RenderCalendar();
         }
   
      };
    
   var XHRcallback =  //this object defines the callback for the XH request
      { 
      success: XHRsuccess, //see XHRsuccess function
        
      failure: function(o) 
         {
         LogMyles("AJAX Connection failed");
         } 
      } ;
   GetMyles(XHRcallback, query, "systemForm");
   }, 
   
/******************************************************************************
Creates the instance of the calendar control, 
and handles any events associated with it.
********************************************************************************/
RenderCalendar = function()
   {
      
   var handleCalendarSelect = function(type, args, obj)
      {  var strMonth, strDay;  
         var YEARPOS = 0, MONTHPOS = 1, DAYPOS = 2;
         var date = args[0][0]; //select first (and in this case, only) date [yyyy, mm, dd]
         var year = date[YEARPOS];//get year
         var month = date[MONTHPOS]; //get month
         var day = date[DAYPOS]; //get day
         
         if(month<10){ strMonth = '0' + month; }
         else { strMonth = '' + month;}  
         
         if(day<10){ strDay = '0' + day; }
         else { strDay = '' + day;}
         
         $("dateTextField").value = strMonth + "/" + strDay + "/" + year; //update selection
         _calendarVisible = false;
         obj.hide(); //hide calendar from display after selection is made
      };
      
   var handleCalendarHide = function()
      {
      _calendarVisible = false;
      };
   
   var init = function()
      {
      var month;
      var currentDate = $("dateTextField").value;
      
      var calendarSettings = 
         {  
         navigator: true,
         title:   _CAL_TITLE, 
         close:true,
         mindate: _MINCALDATE, 
         maxdate: _MAXCALDATE,
         selected: currentDate,
         pagedate: currentDate,
         HIDE_BLANK_WEEKS: true
         }; 
      
      
      _calendarControl = new YAHOO.widget.Calendar("calendarControl","calendarContainer", calendarSettings ); 
      var dateArray = $("dateTextField").value.split("/");
     
      month = parseInt(dateArray[0], _DEFAULT_NUM_BASE);   

      _calendarControl.setMonth(month-1);
      _calendarControl.setYear(parseInt(dateArray[2], _DEFAULT_NUM_BASE));
      _calendarControl.selectEvent.subscribe(handleCalendarSelect, _calendarControl, true);
      _calendarControl.hideEvent.subscribe(handleCalendarHide, _calendarControl, true);
      _calendarControl.render();
      _calendarControl.hide(); //hide from display
      _calendarVisible = false;
      _yuiEvent.addListener("calendarIcon", "click", ToggleCalendar);
      };
   
   _yuiEvent.onDOMReady(init); //render calendar when page is ready. 
         
   }, 
      
/****************************************
Toggles state of the calendar (visible / hidden)
*****************************************/
ToggleCalendar = function()
   {
   _systemChanged["time"] = true; 
   if(_calendarVisible){ _calendarControl.hide(); }
   else { _calendarControl.show();}
   _calendarVisible = !_calendarVisible;
   }, 
   
/******************************************************************
* Validates user input and (if valid) submits it to the server
********************************************************************/  
ValidateSystemForm = function(form)
   {
   SetCursorWait();
   var invalidFlag = false;
   var invalidText = "<b>Please correct the following errors:</b> <br />";
   
   if(_systemChanged["name"] && (Trim($("nameTextField").value)===''))
      {
      invalidFlag = true;
      invalidText += "- Invalid name<br />";
      }
   if(_systemChanged["gip"] && (!VerifyIP(Trim($("gatewayAddressTextField").value))))
      {
      invalidFlag = true;
      invalidText += "- Invalid gateway address<br />";
      }
   if(_systemChanged["ipa0"] && (!VerifyIP(Trim($("ethernetAddressTextField").value))))
      {
      invalidFlag = true;
      invalidText += "- Invalid Ethernet address.<br />";
      }
   if(_systemChanged["mask0"] && (!VerifyIP(Trim($("subnetMaskEth0TextField").value))))
      {
      invalidFlag = true;
      invalidText += "- Invalid subnet mask address on port Eth0<br />";
      }
   if(_systemChanged["ntp"] && (!VerifyIP(Trim($("ntpAddressTextField").value))))
      {
      invalidFlag = true;
      invalidText += "- Invalid ntp server address <br /> ";
      }
   if (SupportsNameserver())
      {
      if(_systemChanged["ns"] && (!$("dhcpEth0CheckBox").checked) && (!VerifyIP(Trim($("nameserverTextfield").value))))
         {
         invalidFlag = true;
         invalidText += "- Invalid Nameserver address <br /> ";
         }
      }
   if(_systemChanged["time"])
      {
      var ret = IsDate(Trim($("dateTextField").value));
      if(ret !=_DATERES.OK)
         {
         invalidFlag = true;
         invalidText += "- " + _DATE_ERR_STR[ret] + "<br />";
         }
      if(!IsTime(Trim($("timeTextField").value)))
         {
         invalidFlag = true;
         invalidText += "- Invalid time.  please enter time in hh:mm:ss format <br />";
         }
      }
   
   if(_systemChanged["timezone"] && (false)) //TODO. Replace "false" for condition that validates time zone. Look for appropriate regex.
      {
      invalidFlag = true;
      invalidText += "- Invalid timezone <br />";
      }


   if((GetProductId()!=_PRODUCT.SIGNEDJE.id)  &&   (GetProductId()!=_PRODUCT.EDJE4111.id))
      {
      if(_systemChanged["ipa1"] && (!VerifyIP(Trim($("gigEAddressTextField").value))))
         {
         invalidFlag = true;
         invalidText += "- Invalid gigE address<br />";
         }
      
      if(_systemChanged["mask1"] && (!VerifyIP(Trim($("subnetMaskEth1TextField").value))))
         {
         invalidFlag = true;
         invalidText += "- Invalid subnet mask address on port Eth1<br />";
         }
            
      }

   if(invalidFlag)
      {
      SetInfoMessage(invalidText, _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.RED);
      SetStatusUpdate();
      }
   else
      {
      SetInfoMessage("Submitting Form.. Please Wait", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GOLD);
      SubmitSystemForm(form); //form valid..  submit to the server.
      } 
   
   return false;
   }, 
  
/************************************
*  Submits the form after validation
*************************************/
SubmitSystemForm = function(form)
   {
   var name, dhcpEth0, dhcpEth1, ethernetAddress, gigEAddress, subnetMaskEth0, subnetMaskEth1, gbeMangementEth1,
      gatewayAddress, ntpAddress, date, time, timeZone, snmp, snmp_ropw, snmp_rwpw, snmp_trap, snmp_sink, servername;

   
   if($("dhcpEth0CheckBox").checked) { dhcpEth0 = "ON"; }
   else { dhcpEth0 = "OFF"; }
   if (SupportsNameserver())
      {
      servername = Trim($("nameserverTextfield").value);
      }
   name = '"'+Trim($("nameTextField").value)+'"';
   gatewayAddress = Trim($("gatewayAddressTextField").value);
   ethernetAddress = Trim($("ethernetAddressTextField").value);
   subnetMaskEth0 = Trim($("subnetMaskEth0TextField").value);
   ntpAddress = Trim($("ntpAddressTextField").value);
   date = ToMMDDYY(Trim($("dateTextField").value));
   time = Trim($("timeTextField").value);
   timeZone = Trim($("timeZoneTextField").value);
   if(SnmpSupported())
      {
      snmp_ropw = Trim($("snmpROPWTextField").value);
      snmp_rwpw = Trim($("snmpRWPWTextField").value);    
      snmp_trap = Trim($("snmpTRPTextField").value);
      if(!IsQamUnit()){snmp_sink = Trim($("snmpPRNMTextField").value);} //NOTE GE 10/26/2010:  This functionality is not available in the TIGER-Branch.  Please remove this condition once it is supported.
      snmp = Trim($("snmpSelect").value);    
      }    
       
   if((GetProductId()!=_PRODUCT.SIGNEDJE.id)  &&   (GetProductId()!=_PRODUCT.EDJE4111.id))
      {
      if($("dhcpEth1CheckBox").checked) { dhcpEth1 = "ON"; }
      else { dhcpEth1 = "OFF"; }
      gigEAddress = Trim($("gigEAddressTextField").value);
      subnetMaskEth1 = Trim($("subnetMaskEth1TextField").value);
      if ((!IsQamUnit())&&(GetProductId()!=_PRODUCT.RD60.id) && (GetProductId() != _PRODUCT.DTA.id))
         {
         gbeMangementEth1 = $("gbeManagementSelect").value;
         }
      }
      
         
   
   var query = '';
   if(_systemChanged["name"]){query+= 'SYSD NA '+name + _NEWLINE; }
   if(_systemChanged["dhcp0"]){query+= 'SYSD DHCP eth0 '+dhcpEth0 + _NEWLINE; }
   if(_systemChanged["ipa0"]){query+= 'SYSD IPA eth0 '+ethernetAddress + _NEWLINE; }
   if(_systemChanged["mask0"]){query+= 'SYSD IPMASK eth0 '+subnetMaskEth0 + _NEWLINE; }
   if(_systemChanged["gip"]){query+= 'SYSD GATEIPADDRESS '+gatewayAddress + _NEWLINE; }
   if(_systemChanged["ntp"]){query+= 'SYSD NTPSVRIPADDRESS 0 '+ntpAddress + _NEWLINE; }
   if(_systemChanged["timezone"]){query+= 'SYSD TIMEZONE '+timeZone + _NEWLINE; }
   if(_systemChanged["snmp"]){query+= 'SYSD SNMP '+snmp + _NEWLINE; }
   if(_systemChanged["snmp_ropw"]){query+= 'SYSD SNMPVAR ROCOMMUNITY '+snmp_ropw + _NEWLINE; }
   if(_systemChanged["snmp_rwpw"]){query+= 'SYSD SNMPVAR RWCOMMUNITY '+snmp_rwpw + _NEWLINE; }
   if(_systemChanged["snmp_trap"]){query+= 'SYSD SNMPVAR TRAPCOMMUNITY '+snmp_trap + _NEWLINE; }
   if(_systemChanged["snmp_sink"]){query+= 'SYSD SNMPVAR TRAP2SINK '+snmp_sink + _NEWLINE; }
   if((SupportsNameserver()) && (!$("dhcpEth0CheckBox").checked) && (_systemChanged["ns"])){query+= 'SYSD NS  '+ servername + _NEWLINE; }
   
   if((GetProductId()!=_PRODUCT.SIGNEDJE.id)&&(GetProductId()!=_PRODUCT.EDJE4111.id)) //eth1 settings are not available for signedge or edge-4111
      {
      if(_systemChanged["dhcp1"]){query+= 'SYSD DHCP eth1 '+dhcpEth1 + _NEWLINE; }
      if(_systemChanged["ipa1"]){query+= 'SYSD IPA eth1 '+gigEAddress + _NEWLINE; }
      if(_systemChanged["mask1"]){query+= 'SYSD IPMASK eth1 '+subnetMaskEth1 + _NEWLINE; }
      }
   if((GetProductId()!=_PRODUCT.RD60.id) && (!IsQamUnit())){
      if(_systemChanged["gbe"])
      {query+='SYSD GBM '+gbeMangementEth1 + _NEWLINE; }
      }
   
   if(_systemChanged["time"]) { query+= 'SYSD TIME '+date+' '+time + _NEWLINE; }
   
   var formXHRSuccess = function(o)
      {
      if(_systemChanged["name"]){   SetDocumentTitle($("nameTextField").value);  }
      SetInfoMessage("Your new settings have been set", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
      };
   
   var XHRcallback =  //this object defines the callback for the XH request
      { 
      success: formXHRSuccess, //see 
        
      failure: function(o) 
         {
         SetStatusUpdate();
         LogMyles("Form submit failed. unable to set new values");
         } 
      } ;
   SetMyles(XHRcallback, query, true, true, LoadSystem); //submit HR request
   
   return false;
    
   
   }, 
   
   
/************************************************************
* Handles the event when a DHCP checkbox is clicked.
***********************************************************/
OnDHCPChange = function
   (
   checkboxObj
   )
   {
   var networkConfirmString = ''
      +  'Changing this field might affect your network configuration\n'
      +  'Click OK to continue'
      ;     
      
      
   switch(checkboxObj.name)
      {
      case "dhcpEth0":
         if(confirm(networkConfirmString))
            {
            if($("ethernetAddressTextField").disabled) { EnableEthFields("eth0"); }
            else { DisableEthFields("eth0");}        
            }
         else //undo
            { 
            if($("ethernetAddressTextField").disabled){ checkboxObj.checked = true; }
            else { checkboxObj.checked = false; }
            } 
         break;
   
      case "dhcpEth1":
         if(confirm(networkConfirmString))
            {
            if($("gigEAddressTextField").disabled) { EnableEthFields("eth1"); }
            else{  DisableEthFields("eth1"); }      
            }
         else //undo
            {
            if($("gigEAddressTextField").disabled){ checkboxObj.checked = true; }
            else {  checkboxObj.checked = false; }
            } 
         break;
      }  
 
   },//end OnDHCPChange function
   
   
/****************************************************************
* Disables Eth Textfields on the system tab
******************************************************************/
DisableEthFields = function
   (
   ethStr
   )
   {
   
   if(ethStr=="eth0")
      {
      $("ethernetAddressTextField").disabled=true;
      $("subnetMaskEth0TextField").disabled=true;
      if(SupportsNameserver()){$("nameserverTextfield").disabled = true;}
      }
   else if(ethStr=="eth1")
      {
      $("gigEAddressTextField").disabled=true;  
      $("subnetMaskEth1TextField").disabled=true; 
      if((!IsQamUnit())&&(GetProductId()!==_PRODUCT.RD60.id) && (GetProductId() != _PRODUCT.DTA.id))
         {
         $("gbeManagementSelect").disabled=true; 
         }
      }
   
   return false;
   },//end DisableEthFields


/****************************************************************
* Enables Textfields on the system tab
******************************************************************/
EnableEthFields = function
   (
   ethStr
   )
   {
   
   if(ethStr=="eth0")
      {
      $("ethernetAddressTextField").disabled=false; 
      $("subnetMaskEth0TextField").disabled=false;
      if(SupportsNameserver()){$("nameserverTextfield").disabled = false;}
      }
   else if(ethStr=="eth1")
      {
      $("gigEAddressTextField").disabled=false; 
      $("subnetMaskEth1TextField").disabled=false; 
      if((GetProductId()!= _PRODUCT.RD60.id) && (!IsQamUnit()) && (GetProductId() != _PRODUCT.DTA.id)) 
         {
         $("gbeManagementSelect").disabled=false; 
         }
      }
   
   return false;
   },//end EnableEthFields
   
   
/********************************************************************
 * Saves status of field on System form
********************************************************************/
OnSystemFieldSelect = function(o)
   {
   _currentField = o.value;
   },


/********************************************************************
 * Alert user when a potentially harmful action might misconfigure the system.
 * Handle user's response accordingly,restoring the status of the form on cancel,
 * or continue processing on confirm.
********************************************************************/
OnSystemFieldChange = function(o)
   {
//NOTE GE 10/07/2009:  
//Deprecated functionality. Popup was confusing for some users.  Expanding HELP blurb instead of displaying this warning.
   }, //end OnSystemFieldChange..
   
/***************************************************************************************
*  Reset Device
***************************************************************************************/  
SubmitReset = function()
   {
   var query =  'CMDD RESET' + _NEWLINE;
   if (GetProductId() == _PRODUCT.DTA.id)
      {
      query = 'SYSD RESET' + _NEWLINE;
      }
  
   var XHRSuccess = function(o)
      {
      SetInfoMessage("Resetting Device.... Please Wait", 3000,_ADTCOLOR.GREEN);
      setTimeout(TestConnection, 5000); //attemtp reconnection in 5 secs
      };
   
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
        {
         LogMyles("Reset failed");
         }
         
      };
   
   SetMyles(XHRCallback, query, false, false, null); //submit XH request
   if((_resetModalPanel!==undefined) && (_resetModalPanel!== null)){HideResetWarningPanel();}
   },
   
   


/*******************************************************************************
 *    ShowResetWarningPanel -- Displays the warning panel
 ******************************************************************************/
ShowResetWarningPanel = function() 
   {
   _resetModalPanel.show();
   },

/*******************************************************************************
 *    HideResetWarningPanel -- Hides the warning panel
 ******************************************************************************/
HideResetWarningPanel = function() 
   {
   _resetModalPanel.hide();
   },


ResetSystemChangedFlags = function()
   {
   _systemChanged["name"] = false;  _systemChanged["gip"] = false; _systemChanged["dhcp0"] = false;  
   _systemChanged["dhcp1"] = false; _systemChanged["gbe"] = false; 
   _systemChanged["ipa0"] = false;
   _systemChanged["ipa1"] = false; _systemChanged["mask0"] = false;  _systemChanged["mask1"] = false;
   _systemChanged["ntp"] = false; _systemChanged["timezone"] = false; _systemChanged["time"] = false;
   _systemChanged["snmp"] = false; _systemChanged["snmp_rwpw"] = false; _systemChanged["snmp_ropw"] = false;
   _systemChanged["snmp_trap"] = false; _systemChanged["snmp_sink"] = false; _systemChanged["ns"] = false;
   },
   
   
/***********************************************************************************
 * Returns true if the product supports SNMP.
 * False otherwise
 ***********************************************************************************/
SnmpSupported = function()
   {
   return (IsEncoderUnit() || IsPlayerUnit() || IsQamUnit()||(GetProductId()==_PRODUCT.RD60.id));
   }

   ;
   /*****************************************************************************
 * @file
 * @author  Original:      German Escallon
 * @author  Contributors:  German Escallon
 * @date    Created:       August 28 2010
 * @date    Last Edit:     $Date$ by $Author$
 * 
 * Description: This file handles the ADTEC Temperature monitor
 *****************************************************************************/

//Adtec Thermostat constructor
ADTEC_THERMOSTAT = function()
   {
//   this.notReadyCounter = 0; //See GE 09/30/2010 note below
   this.showWarningPanel = function(msg)
      {
         
      var panelConf = 
         { 
         width: "300px",
         fixedcenter: true,
         autofillheight :"body",
         modal :true,
         visible: true,
         draggable: true,
         close: true,
         constraintoviewport: true,
         buttons: [ { text:"OK", handler:this.hide, isDefault:true }]
         };
      
      var panelDiv = CreatePanelDiv();
      
      var panelBody = ''
         +  '<center><p><div id="thWarningMessageSection">' + msg + '</div><br />'
//         +  '<a id="thWarningOK"><img src="/images/ok.gif"></img></a>'
         +  '<a id="thWarningOK"><button>OK</button></img></a>' //TODO:  replace button for a customized image. (See commented line above).
         +  '</p></center>'
         ;
      if(this.panelObj!== null){this.panelObj = null;}
      this.panelObj = new YAHOO.widget.Panel(panelDiv.id, panelConf);
      this.panelObj.setHeader("<center><b>!! WARNING !!</b></center>");
      this.panelObj.setBody(panelBody);
   
      //hiding the elemtn is the same as destroying it for our purposes.
      var onPanelHide = function()
         {
         this.destroy();
         };
   
      //adds listener to OK button that destroys the panel once user has acknowledge receving the message of the temperature warning.
      var onPanelRender = function()
         {
         _yuiEvent.addListener("thWarningOK", "click",  function(obj){ this.destroy();},  this,  true );
         };

      //add subscriptions
      this.panelObj.renderEvent.subscribe(onPanelRender);
      this.panelObj.hideEvent.subscribe(onPanelHide);
   
      this.panelObj.render();
   
      
      };

   /**************************************************************************************************
    * Monitors the internal temperature of the Encoders that support this functionality. (ENXX series).
    ***************************************************************************************************/
   this.monitorEncoders = function()
      {
      //Enum to distinguish the current temperature state
      var TEMPSTATE =  
         {
         "NORMAL":   0,
         "WARM":     1,
         "HOT":      2,
         "CRITICAL": 3
         };
      var currTmp = setting["ecmd_vms_tmp"];
      if((currTmp===undefined)||(currTmp===null)||(isNaN(currTmp)))
         {//status panel has not fully loaded.
         /*
          * NOTE GE 09/30/2010:
          *    This case occurs when the browser loses communication w/ the unit, or when the user has reset 
          *    to the factory default settings (No keys are enabled.). Commenting out warning message to the user.  
          */
//         if((this.notReadyCounter)++ > 3)
//            {//status panel is in a fault state, or temperature reading has failed.  Warn User of this (very unlikely) scenario
//            if(GetUiState()==_UISTATE.INSYNC){this.showWarningPanel("Unable to read your device's temperature.  Please monitor and shut down if it reaches " + this.TEMP.CRITICAL + "(C) or more.");}
//            this.notReadyCounter = 0; //resets counter
//            }
         return;
         }
      else
         {
//         this.notReadyCounter = 0; //resets counter -> see GE 09/30/2010 note above
         var warningLevel = 0;
         
         if(currTmp>this.TEMP.WARM)
            {
            warningLevel++;
            if(currTmp>this.TEMP.HOT)
               {
               warningLevel++;
               if(currTmp>this.TEMP.CRITICAL)
                  {
                  warningLevel++;
                  }
               }
            }
         if(this.currState===null){this.currState = TEMPSTATE.NORMAL;} //intialize current state 
         
         switch(warningLevel)
            {
            case 0:  //Temperature is normal
               this.currState = TEMPSTATE.NORMAL;
               break;
            
            case 1:
               if(this.currState < TEMPSTATE.WARM)
                  {
                  this.showWarningPanel("<b>Attention!</b> Your device is running warmer than normal. Please monitor.");
                  }
               this.currState = TEMPSTATE.WARM; //updates the current temperature state.
               break;
            case 2:
               if(this.currState < TEMPSTATE.HOT)
                  {
                  this.showWarningPanel("<b>! Warning !</b> Your device is running increasingly warm, please confirm that all fans are fully functional.");
                  }
               this.currState = TEMPSTATE.HOT; //updates the current temperature state.
               break;
            
            case 3:
               if(this.currState < TEMPSTATE.CRITICAL)
                  {
                  this.showWarningPanel("<b>!! TEMPERATURE ALARM !!</b> Please shut your device down immediately and contact Adtec Customer Support for assistance.");
                  this.currState = TEMPSTATE.CRITICAL; //updates the current temperature state.
                  }
               break;
            }
         }
      };

      
/**************************************************************************************************
 * detects the current device, and calls the appropriate handler. 
 **************************************************************************************************/
   this.monitor = function()
      {
      switch(GetProductId())
         {
         case _PRODUCT.EN40.id:
         case _PRODUCT.EN80.id:
         case _PRODUCT.EN41.id:
         case _PRODUCT.EN81.id:
         case _PRODUCT.EN91.id:
         case _PRODUCT.MEDIAHUBHD_422.id:
            this.monitorEncoders();
            break;
            
         default: //Found a product not supported by the thermostat
            break;
         }
      };
      
   };

   //Class members
ADTEC_THERMOSTAT.prototype = 
   {
      
   //defines the temperature state thresholds
   TEMP: 
      {
      "WARM":        55,
      "HOT":         65,
      "CRITICAL":    75
      },
      
   //keeps track of the current temperature state   
   currState:        null,
   panelObj:         null
      
   };

/*****************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file handles the upgrade tab
 *****************************************************************************/ 

/***************************************************************************************************
 *                                  FIRMWARE TAB Global Constants.
 *
 * NOTE:  const Keyword is not supported by Internet Explorer. Thus var is used instead.  
 * Treat these variables as #define's (in C/C++ code terms)and (even though its possible)  DO NOT 
 * re-assign any value to them at run time.                                            
****************************************************************************************************/
var
   //Enum that defines the different actions to do when handling firmware versions
   //NOTE:  Must be in sync w/ TVersionAction enum on the server.  (see <project>/app/myles/requestHandler.cpp)
   _VERSION = 
      {
      "EXTRACT":           0, //extracts the selected version
      "UPDATE":            1, //updates unit to selected version
      "DELETE_FILE":       2, //deletes (uninstalled) firmware file (tarball)
      "DELETE_VERSION":    3  //removes an installed firmware version from the filesystem
      },      
   
   _UPGRADE_PANEL_WIDTH =                       "300px",
   _UPGRADE_VRSN_COL_WIDTH =                    "490px", 
   _UPGRADE_ACTION_COL_WIDTH =                  "71px",
   _VRSN_UPDATE_RECONNECT_INIT_TIMEOUT =        40,
   _VRSN_UPDATE_RECONNECT_TIMEOUT =             20000,
   _VRSN_UPDATE_RECONNECT_INTERVAL =            5,
   _ADTEC_FIRMWARE_EXTENSION =                  ".nfcms",
   _VRSN_RESTORE_TIMEOUT =                      90000,
   _VRSN_UNINSTALLED_TABLE_REFRESH_RATE =       15000
   ;
   

/****************************************************************************************************
                                  UPGRADE TAB Global Variables
****************************************************************************************************/
var 
   _installedVersionsSource,
   _installedVersionsTable,
   _uninstalledVersionsSource,
   _uninstalledVersionsTable,
   _installedVersions, 
   _uninstalledVersions,
   _hiddenModalPanel,
   _newtecVersionsSource,
   _newtecVersionsTable,
   _newtecProgressBar
   ;
   
var
pbUpgradeCfg = {"value": 0, "minValue": 0, "maxValue": 100, "width": 440, "height": 15},
/***************************************************************************************
*  Handles the tab that performs firmware Updates 
***********************************************************************************/
RenderFirmware = function()  
   {
   //if(GetProductId()==_PRODUCT.DPI.id){  HideSubNavigation(); }// temp added 
   LoadUpgrade();
   var firmwareHTML = ''
      +  '<table width="99%" cellspacing="0" cellpadding="4" valign="top">'
      + '<tr id="installedVersionsRow"><td>'
      + '   <h3>Installed Firmware Versions <img id="istvHint" onclick="ShowHelp(&quot;hlp_istv&quot;, this);" src="/images/hints.gif"/></h3> '
      + '   <div id="installedVersionsTable" ></div>'
      + '</td></tr>' 
      + '<tr><td><div id="hiddenPanelDiv" style="background-color:#CC9933;"></div></td></tr>'
      + '<tr id="uninstalledVersionsRow" style="display:none;"><td>'
      + '   <br /><h3>Available Firmware Versions <img id="avavHint" onclick="ShowHelp(&quot;hlp_avav&quot;, this);" src="/images/hints.gif"/></h3>'
      + '   <div id="uninstalledVersionsTable" ></div>'
      + '</td></tr>'
      ;
   
   if(HasNewtecDemod())
      {
      firmwareHTML += ''
         + '<tr id="newtecVersionsRow" style="display: none;"><td>'
         + '<br/><h3>Available Newtec Firmware Versions</h3>'
         + '<div id="newtecVersionsTable"></div>'
         + '</td></tr>'
         + '<tr id="newtecUpgradeRow" style="display: none;"><td>'
         + '<br/><h3>Active Newtec Firmware Upgrade</h3>'
         + '<table style="width: 700px">'
         + '<tr>'
         + '<td>Start Time:</td><td id="upgradeStartTime"></td>'
         + '</tr>'
         + '<tr>'
         + '<td colspan="3"><div id="upgradePercentComplete"></div></td>'
         + '<td id="upgradePercentLabel"></td>'
         + '</tr>'
         + '</table>'
         + '</td></tr>'
         ;
      }
   
   firmwareHTML += '</table>';
   _newtecProgressBar = new YAHOO.widget.ProgressBar(pbUpgradeCfg);
   $("main_div").innerHTML = firmwareHTML;
   },
   
   
LoadUpgrade = function(){
   GetVersions(_REQID.GETINSTALLEDFIRMWARE);
   GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);
   if (HasNewtecDemod())
      {
      var query = ''
         + '&q=SYSD+SUP+FIRMWARE+LIST'
         + '&q=SYSD+SUP+FIRMWARE'
         ;
      var XHRSuccess = function(o)
         {
         if (ParseResponse(o))
            { 
            if (setting.sysd_sup.update)
               {
               DisplayUpgradeStatus();
               }
            else
               {
               DisplayNewtecVersions(setting.sysd_sup.file);
               }
            }
         };
         
      var XHRcallback = 
         {
         success :XHRSuccess,
         failure : function(o) 
            {
            LogMyles("AJAX Error.  Available Newtec firmware could not be captured.  Response: "     + o.responseText);
            }
         };
      //submit XH request
      GetMyles(XHRcallback, query, "installedVersionsRow");
      }
   _yuiEvent.onAvailable("installedVersionsRow", LoadUpgradePanel);
   },
   
LoadUpgradePanel = function()
   {
   var panelConf = 
      {
      width:_UPGRADE_PANEL_WIDTH, modal:true, visible:false, 
      autofillheight: "body", close:false, draggable:true
      };
   _hiddenModalPanel = new YAHOO.widget.Panel("hiddenPanelDiv", panelConf);
   
   var panelBody = ''
   
      +  '<table style="background-color:#FFFFFF;">'
      +  '  <tr>'
      +  '     <td align="center"><img src="/images/spinner.gif" /></td>'
      +  '  </tr>'
      +  '  <tr>'
      +  '     <td><div id="upgradeStatusDiv"></div></td>'
      +  '  </tr>'
      +  '</table>'
      ;
   
   _hiddenModalPanel.setHeader("<b>Adtec Digital</b>");
   _hiddenModalPanel.setBody(panelBody);
   _hiddenModalPanel.render();
   },
   
/***************************************************************************************
*  Gets the versions (installed or uninstalled), and call function that creates the datatable, 
* passing the found versions as an argument in an array. 
***************************************************************************************/
GetVersions = function
   (
   reqId
   )
   {
   var XHRSuccess = function(o)
      {
      try 
         {
         var jsonObj = _yuiParseJson(o.responseText);
         var versionsObj = jsonObj.Versions;
         var versionArray = [];
         
         if(versionsObj===undefined)
            {
            //no versions
            LogMyles("No versions found");
            $("uninstalledVersionsRow").style.display = "none";
            }
         else
            {
            for(var i=0; i<versionsObj.length; i++)
               {
               var tempVersionObj = 
                  {
                  version: versionsObj[i].version               
                  };
               versionArray.push(tempVersionObj);
               }
            }
         
         if(reqId==_REQID.GETINSTALLEDFIRMWARE)
            {
            DisplayInstalledVersions(versionArray);
            }
         else if(reqId==_REQID.GETUNINSTALLEDFIRMWARE)
            {
            if(versionArray.length===0)
               { //hide uninstalled versions section
               
               $("uninstalledVersionsRow").style.display = "none";
               }
            else
               {  //show uninstalled version section and create datatable
               $("uninstalledVersionsRow").style.display = "";
               DisplayUninstalledVersions(versionArray);
               }
            }   
         }  
      catch(e)
         {
         LogMyles("error retrieving installed versions");
         }
      };
   
   var XHRCallback = 
      {
      success: XHRSuccess, 
      failure: function(o)
         {
         LogMyles("installed version could not be retrieved");
         }   
      };
      
   var postdataObj = 
      { 
      id: reqId,
      req: Math.random() 
      };
  
   var postdataStr = _yuiStringify(postdataObj); //transform object to string 
   ConnectToReqHandler(XHRCallback, postdataStr, false); 
   },


/*******************************************************************************************
 *  Displays a list of all the available firmware versions in a datatable.  Also, subscribes to 
 *  events to handle the datatable operations (select, delete, etc..)
 ******************************************************************************************/
DisplayInstalledVersions = function
   (
   insArray
   )
   { 
   
   _installedVersionsSource = new YAHOO.util.DataSource(insArray);
   _installedVersionsSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
   
   _installedVersionsSource.responseSchema = 
      {
      fields      : ['version'] 
      };
    
   var installedVersionsTableConfig = 
      {  
      initialRequest:'',
      sortedBy:{key:"version",dir:"asc"},
      paginator: new YAHOO.widget.Paginator({rowsPerPage:5, alwaysVisible:false})  
      }; 
   
   
   var myColumnDefs = 
   [
      {
      key:"version",
      label:'<b>Versions</b>', 
      sortable:true,
      selected:false,
      formatter:function(elCell, oRecord, oColumn, oData)
         {
         var versionText = ''
         + "Version " 
         + oData.substring(oData.lastIndexOf("/")+1, oData.length); //remove path
         
         elCell.innerHTML = versionText; 
         elCell.style.width = _UPGRADE_VRSN_COL_WIDTH;
         }
      }, 
      {
      key:'update',
      label:'<b>Update</b>',
      formatter: function(elCell, oRecord) 
         {
         elCell.style.cursor = 'pointer';
         var versionName = oRecord.getData("version");
         if(versionName.indexOf("current selection") != -1) //current version record
            {
            // NOTE GE 10/28/2009.
            // Some units do NOT support RESTORE functionality.
            if(RestoreSupported())
               {
               elCell.innerHTML = '<a><img src="/images/restore.gif" /></a>';
               }
            else
               {
               elCell.innerHTML = '<a><img src="/images/disabled.gif" /></a>';
               }
            
            }
         else 
            { 
            elCell.innerHTML = '<a><img src="/images/select.gif" /></a>';
            }
         
            
         elCell.style.width = _UPGRADE_ACTION_COL_WIDTH;
         }
      },
      {
      key:'delete',
      label:'<b>Delete</b>',
      formatter: function(elCell, oRecord) 
         {
         var versionName = oRecord.getData("version");
         if(versionName.indexOf("current selection") != -1) //current version record
            {
            elCell.innerHTML = '<img src="/images/disabled.gif" />'; 
            elCell.style.cursor = 'default';
            }
         else
            {
            elCell.innerHTML = '<img src="/images/delete.gif" />';
            elCell.style.cursor = 'pointer';
            }
               
         elCell.style.width = _UPGRADE_ACTION_COL_WIDTH;
         }//end formatter
      } //end delete column
   ]; //end columnDef
   
   
   //instantiate datatable
   _installedVersionsTable = new YAHOO.widget.DataTable("installedVersionsTable", myColumnDefs, 
                                                _installedVersionsSource, installedVersionsTableConfig);
   
   _installedVersionsTable.subscribe(
      'cellClickEvent',
      function
      (
      ev
      ) 
      {
      var target = YAHOO.util.Event.getTarget(ev);
      var column = _installedVersionsTable.getColumn(target);
      var record = this.getRecord(target);
      var version = record.getData("version");
      switch(column.key)
         {
         
         case 'update': 
               
            var confirmString = ''
               +  'Please confirm firmware update.  The system will reboot with the '
               +  ' selected firmware version. You will lose connectivity for a few minutes.'
               ;
                              
            if(version.indexOf("current selection") != -1)
               {
               // NOTE GE 10/28/2009.
               // some units do NOT support RESTORE functionality.
               // This is a temporary condition that should be removed once these products are
               // merged back into head.
               if(RestoreSupported())
                  {
                  var restoreConfirm = ''
                  +  'Please confirm firmware restore action. '
                  +  'The system will reboot with factory default settings'
                  ;
                  if(confirm(restoreConfirm))  //user must confirm action twice before proceeding
                     {
                     restoreConfirm = ''
                        +  'THIS WILL ERASE ALL OF YOUR CURRENT CONFIGURATIONS AND RETURN THIS UNIT '
                        +  'TO FACTORY DEFAULTS. YOU CANNOT UNDO THIS ACTION.'
                        ;
                     if(confirm(restoreConfirm)) //Since this is a non-reversible change, we ask for double confirmation of this change
                        {
                        RestoreUnit();
                        }
                     }                 
                  }
               }
            else
               {
               if(confirm(confirmString))
                  {   
                  StopStatusUpdate();
   
                  SetInfoMessage('Performing update. This might take a few minutes while server reboots.');
                  
                  SetAnimationPanel();
                  $("upgradeStatusDiv").innerHTML = ''
                     +  'Please wait.  Unit is updating.  This process might take a couple of minutes..'
                     ;
                     
                  VersionHandler(_VERSION.UPDATE, version);
                  SetCursorWait();
                  }   
               }               
            break;
               
         case 'delete':
                 
            if(version.indexOf("current selection") == -1)
               {
               if(confirm("Please confirm version delete"))
                  {   
                  SetAnimationPanel();
                  $("upgradeStatusDiv").innerHTML = ''
                     +  'Please wait.  Firmware version ' + version + ' is being deleted..'
                     ;
                  VersionHandler(_VERSION.DELETE_VERSION, version);
               }
            }
            break;
       
            
         }
   
      } 
   ); //end subscribe cellclickevent
    
      
   },
   
 
   
   
   
/***************************************************************************************
*  Displays available (not extracted) versions 
***********************************************************************************/
DisplayUninstalledVersions = function
   (
   uninsArray
   )
   { 
   
   _uninstalledVersionsSource = new YAHOO.util.DataSource(uninsArray);
   _uninstalledVersionsSource.connMethodPost = true;
   _uninstalledVersionsSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
   _uninstalledVersionsSource.responseSchema = 
      {
      //resultsList : 'Versions',
      fields      : ['version'] 
      };
   
   //only show table if there are available records
   _uninstalledVersionsSource.subscribe("responseParseEvent",function() {}); 
   
   var uninstalledVersionsTableConfig = 
      {  
      initialRequest:'',
      sortedBy:{key:"version",dir:"asc"}
      }; 
   
   
   var myColumnDefs = 
   [
      {
      key:"version",
      label:'<b>Versions</b>', 
      sortable:true,
      selected:false,
      formatter:function(elCell, oRecord, oColumn, oData)
         {
         elCell.innerHTML = ParseUninstalledVersionPath(oData); 
         elCell.style.width = _UPGRADE_VRSN_COL_WIDTH;
         
         }
      }, 
      {
      key:'install',
      label:'<b>Install</b>',
      formatter: function(elCell, oRecord) 
         {
         elCell.innerHTML = '<a><img src="/images/install.gif" /></a>';
         elCell.style.cursor = 'pointer'; 
         elCell.style.width = _UPGRADE_ACTION_COL_WIDTH;
         } 
      },
      {
      key:'delete',
      label:'<b>Delete</b>',
      formatter: function(elCell, oRecord) 
         {
         elCell.innerHTML = '<a><img src="/images/delete.gif" /></a>';
         elCell.style.cursor = 'pointer'; 
         elCell.style.width = _UPGRADE_ACTION_COL_WIDTH;
         }
      }
   ]; //end column definitions array  
   
   //instantiate datatable
   _uninstalledVersionsTable = new YAHOO.widget.DataTable("uninstalledVersionsTable", myColumnDefs, 
                                                _uninstalledVersionsSource, uninstalledVersionsTableConfig);
   
   _uninstalledVersionsTable.subscribe('cellClickEvent', function ( ev ) 
      { 
      var target = YAHOO.util.Event.getTarget(ev);
      var column = _uninstalledVersionsTable.getColumn(target);
      var record = this.getRecord(target);
      var filename = record.getData("version");
      
      switch(column.key)
         {
      
         case 'install': 
            if(confirm("Are you sure that you want to install the selected version?"))
               {
               StopStatusUpdate();
               SetInfoMessage('Extracting Firmware File.', null, _ADTCOLOR.GOLD);
                  
               SetAnimationPanel();
               $("upgradeStatusDiv").innerHTML = ''
                  +  'Please wait.  Firmware file is being extracted. '
                  +  'This process might take a couple of minutes'
                  ;
               
                                       
               VersionHandler(_VERSION.EXTRACT, filename);
               }
            break;
         
         case 'delete':
            if(confirm("Please confirm version delete"))
               {
               VersionHandler(_VERSION.DELETE_FILE, CleanupString(filename));
               }
            break;
         
         }

      } 
   ); //end subscribe cellclickevent
    
      
   }, 
 

   

/*******************************************************************************************
 * Handles all of the different operations for datatable entries. 
 * (Delete, extract, install, update, etc..).  Communicates w/ the server via AJAX.
 ******************************************************************************************/
VersionHandler = function
   (
   pAction,
   pName 
   )
   {
   var successHandler = function(o)
      {
      var errRegex = /^\s*Error[.]*/im;
      if(errRegex.test(o.responseText))
         {
         SetInfoMessage(o.responseText, _DEFAULT_INFO_MSG_TIMEOUT, _ADTCOLOR.RED);
         ResetAnimationPanel();
         return;
         }
      
      switch(pAction)
         {
         case _VERSION.DELETE_FILE:
          
            SetInfoMessage("File " + pName + " succesfully deleted.", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
            GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);
            break;
          
         case _VERSION.EXTRACT:
            SetInfoMessage("Version " + pName + " succesfully extracted", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
            GetVersions(_REQID.GETINSTALLEDFIRMWARE);
            GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);
            ResetAnimationPanel();
             break;
         
         case _VERSION.DELETE_VERSION:         
            SetInfoMessage("Version " + pName + " succesfully deleted", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
            GetVersions(_REQID.GETINSTALLEDFIRMWARE);
            GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);
            ResetAnimationPanel();
            $("boxStatus").innerHTML = '';
            break;
       
         case _VERSION.UPDATE: //server is restarting
            var msg = "Server is rebooting.\nAttempting to reconnect in " + (_VRSN_UPDATE_RECONNECT_INIT_TIMEOUT/_MILISECONDSPERSECOND) + " seconds ...";
            SetInfoMessage(msg, _VRSN_UPDATE_RECONNECT_TIMEOUT,_ADTCOLOR.GREEN);
            setTimeout(TestConnection, _VRSN_UPDATE_RECONNECT_TIMEOUT);
            break;   
         }
         
      };
  /*
   * ERR=([128]="Insufficient Space" [129]="Gnu Missing" [130]="Invalid Version" \
[131]="Invalid Firmware" [132]="Extraction Failed" [133]="Extraction Busy" \
[134]="Remount failed" [135]="Kernel Update Failure" [136]="Delete Failed" \
[137]="Cannot determine GNU" [138]="Unable to select version" \
[139]="Netboot system.  Vrsn not available." [140]="Vrsn already selected, waiting for reboot")
   */
 
   var failureHandler = 
      function(o)
         {
         LogMyles("Ajax Error.  " + o.status + ":" + o.responseText);
         };
     
   
   //define callback object
   var XHRCallback =
      {
      success: successHandler, 
      failure: failureHandler
      };
   
   var postdataObj = 
      {
      id:     _REQID.HANDLEVERSION,
      action: pAction, //delete, update, extract, deletefile..
      name: pName //filename for deletefile and extract - version name for update and deleteversion     
      };
   
   var postdataStr = _yuiStringify(postdataObj);
   ConnectToReqHandler(XHRCallback, postdataStr);
   
   },

/*******************************************************************************************
 *  Displays the modal animation panel, and stops updating the status panel to prevent 
 *  server overload.
 ******************************************************************************************/ 
SetAnimationPanel = function()
   {
   _hiddenModalPanel.show();
   SetCursorWait();
   StopStatusUpdate();
      
   },
   

/*******************************************************************************************
 *  Resets the modal animation panel, and resumes interaction with the server to update 
 *  the status panel.
 ******************************************************************************************/ 
ResetAnimationPanel = function()
   {
   _hiddenModalPanel.hide();
   ResetCursor();
   SetStatusUpdate();
   },   
 
/****************************************************************
*  Gets full path and filename of unextracted firmware files
*  Returns version in a user friendly format, hiding the path in the filesystem
*  e.g:  
*  Input: /media/hd0/firmware/mediahub-hd-v3.01.19.nfcms.tgz 
*  Output: Version 3.01.19
*****************************************************************/
ParseUninstalledVersionPath = function
   (
   versionPath
   )
   {
   var regex = /^[\/|\w|_|\-|\\]*\-v([\d|_|\w|\-|\.|\\]*)\.nfcms\.[\w]*$/i;
   var vrsn = versionPath.replace(regex, "$1");
   var result = "Version " + vrsn; //removes path and extension
   
   return result;
   },


   

   
/*******************************************************************************************
 * Restores firmware configurations. This operation requires rebooting the system, causing it to 
 * stop responding for a few minutes. 
 ******************************************************************************************/ 
RestoreUnit = function()
   {
   
   var XHRCallback = 
      {
      success: function(o)
         {
//         var response = ParseLocally(o.responseText);
         StopStatusUpdate();
         SetInfoMessage('Performing firmware restore. This might take a few minutes while server reboots.');
                           
         SetAnimationPanel();
         $("upgradeStatusDiv").innerHTML = ''
            +  'Please wait.  Your ' + _product.name + ' is rebooting to factory settings. '               
            +  'This process might take a couple of minutes.'
            ;
         SetCursorWait();
         
         var q = '';
//         if(GetProductId()==_PRODUCT.DTA.id)
//            {
//            resetQuery = 'SYSD RESET';
//            }
//         else
//            {
//            resetQuery = 'CMDD RESET REINIT ' + response.sysd_na + ''+_NEWLINE ;
//            }
         switch(GetProductId())
            {
            case _PRODUCT.EDJE5110.id:
            case _PRODUCT.EN40.id:
            case _PRODUCT.EN41.id:
            case _PRODUCT.EN80.id:
            case _PRODUCT.EN81.id:
            case _PRODUCT.EN91.id:
            case _PRODUCT.EDJE5110.id:
            case _PRODUCT.MEDIAHUBHD.id:
            case _PRODUCT.MEDIAHUBHD_422.id:
               q+= ''
                  + 'ECMD CF ERASE' + _NEWLINE
                  + 'SYSD CF ERASE' + _NEWLINE
                  ;
               if(DecoderPresent())
                  {
                  q+= ''
                  + 'DCMD CF ERASE' + _NEWLINE
                  ;
                  }
               break;
               
            case _PRODUCT.SIGNEDJE.id:
            case _PRODUCT.EDJE4111.id:
            case _PRODUCT.SOLOIST411_HW2.id:
            case _PRODUCT.SOLOISTHDPRO.id:
            case _PRODUCT.RD60.id:
               q+= ''
                 + 'DCMD CF ERASE' + _NEWLINE
                 ;
              break;
              
            case _PRODUCT.HDMI2QAM.id:
            case _PRODUCT.YUV2QAM.id:
            case _PRODUCT.EN10.id:
            case _PRODUCT.EN20.id:
               q  += ''
                  + 'ECMD0 CFG ERASE' + _NEWLINE
                  + 'ECMD1 CFG ERASE' + _NEWLINE
                  ;
                  break;
            }
            
         var resetSuccess = function(o)
            {
            };

         var resetCallback =  
            {
            success: resetSuccess,
            failure: function(o)
               {
               LogMyles("Error: Could not restore unit to factory defaults");
               alert("Error: Could not restore unit to factory defaults");
               }
            };
         setTimeout(function() {SetMyles(resetCallback, q, false, false, SubmitReset);}, 1000);
         },
      failure: function(o)
        {
         LogMyles("Error: Could not restore unit to factory defaults");
         alert("Error: Could not restore unit to factory defaults");
         }
      };
   
   var query = '';
   switch(GetProductId())
      {
      case _PRODUCT.EDJE5110.id:
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
      case _PRODUCT.EDJE5110.id:
      case _PRODUCT.MEDIAHUBHD.id:
      case _PRODUCT.MEDIAHUBHD_422.id:
         query+= 'ECMD STOP' + _NEWLINE;
         if(DecoderPresent())
            {
            query += 'DCMD STOP' + _NEWLINE;
            }
         break;
         
      case _PRODUCT.SIGNEDJE.id:
      case _PRODUCT.EDJE4111.id:
      case _PRODUCT.SOLOIST411_HW2.id:
      case _PRODUCT.SOLOISTHDPRO.id:
      case _PRODUCT.RD60.id:
         query+= 'DCMD STOP' + _NEWLINE;
        break;
        
      case _PRODUCT.HDMI2QAM.id:
      case _PRODUCT.YUV2QAM.id:
      case _PRODUCT.EN10.id:
      case _PRODUCT.EN20.id:
         query  += ''
            + 'ECMD0 STOP' + _NEWLINE
            + 'ECMD1 STOP' + _NEWLINE
            ;
            break;
      }
   
   SetMyles(XHRCallback, query, false, false, null);
   
   },
   
/*******************************************************************************************
 * Displays message that lets the user know that the restoration of the system has been completed.
 * This might never occur at all, since the IP of the unit might (most likely) have changed,
 * causing it not to respond at all.
 ******************************************************************************************/ 
OnRestoreComplete = function()
   {
   SetInfoMessage("<b>Restore Complete.</b>", 10000,_ADTCOLOR.GREEN);
   var restoreMessage = ''
      +  'Your unit has restored succesfully.  Settings have been reversed to factory defaults '
      +  'including your IP address.  Wait a few minutes while server reboots, and &gt;&gt; <a href="http://192.168.10.48" target="_blank"> Click Here http://192.168.10.48</a> &lt;&lt; to reconnect to it.<br />'
      +  'If the link above does not work, check your IP settings or contact your network administrator.' 
      +  '<br /><br /><b>'
      ;
   _hiddenModalPanel.setBody(restoreMessage);
   },
   
   
/*********************************************************
 * Returns TRUE if the restore functionality is available for the unit.
 * Returns FALSE otherwise.
 *******************************************************/
RestoreSupported = function()
   {
   var result = true;
   switch(GetProductId())
      {
      case _PRODUCT.DTA.id:
      case _PRODUCT.RD70.id:
         result = false;
         break;
      
      default:
         result = true;
      }
   return result;
   },
   
/************************************************************************************
 *  Displays available newtec versions 
 ***********************************************************************************/
DisplayNewtecVersions = function
   (
   fileArray
   )
   {
   $("newtecUpgradeRow").style.display = "none";
   _newtecVersionsSource = new YAHOO.util.DataSource(fileArray);
   _newtecVersionsSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
   
   _newtecVersionsSource.responseSchema = 
      {
      fields      : ['version'] 
      };
    
   var newtecVersionsTableConfig = 
      {  
      initialRequest:'',
      sortedBy:{key:"version",dir:"asc"},
      paginator: new YAHOO.widget.Paginator({rowsPerPage:5, alwaysVisible:false})  
      }; 
   
   
   var myColumnDefs = 
   [
      {
      key:"version",
      label:'<b>Versions</b>', 
      sortable:true,
      selected:false,
      formatter:function(elCell, oRecord, oColumn, oData)
         {
         var versionText = ''
         + "Version " 
         + oData.replace(".ntc.tgz", "");
         
         elCell.innerHTML = versionText; 
         elCell.style.width = _UPGRADE_VRSN_COL_WIDTH;
         }
      }, 
      {
      key:'update',
      label:'<b>Update</b>',
      formatter: function(elCell, oRecord) 
         {
         elCell.style.cursor = 'pointer';
         elCell.innerHTML = '<a><img src="/images/select.gif" /></a>';
         elCell.style.width = _UPGRADE_ACTION_COL_WIDTH;
         }
      }
   ]; //end columnDef
   
   
   //instantiate datatable
   _newtecVersionsTable = new YAHOO.widget.DataTable("newtecVersionsTable", myColumnDefs, 
                                                _newtecVersionsSource, newtecVersionsTableConfig);
   
   _newtecVersionsTable.subscribe(
      'cellClickEvent',
      function
      (
      ev
      ) 
      {
      var target = YAHOO.util.Event.getTarget(ev);
      var column = _newtecVersionsTable.getColumn(target);
      var record = this.getRecord(target);
      var version = record.getData("version");
      if (column.key == "update")
         {
         
         var confirmString = ''
            +  'Please confirm firmware update.  The system will install the selected firmware'
            +  ' version. You will not lose connectivity, but the installation will take at least'
            +  ' several minutes.'
            ;
         if(confirm(confirmString))
            {
            var query = '&q=SYSD+SUP+FIRMWARE+BEGIN+' + version;
            var XHRCallback = 
               {
               success: function(o)
                  {
                  setting.sysd_sup.update = true;
                  setting.sysd_sup.percent_complete = 0;
                  setting.sysd_sup.start_time = "Now";
                  SetInfoMessage('Performing update. This might take a few minutes.');
                  setTimeout(DisplayUpgradeStatus, 2000);
                  },
               failure: function(o)
                  {
                  LogMyles("Error: Failed to begin newtec firmare upgrade.");
                  alert("Error: Failed to begin newtec firmare upgrade.");
                  }
               };
            GetMyles(XHRCallback, query);
            }
         }
   
      } 
   ); //end subscribe cellclickevent
   if (fileArray.length > 0)
      {
      $("newtecVersionsRow").style.display = "";
      }
   },

/************************************************************************************
 *  Displays newtec upgrade status
 ***********************************************************************************/
DisplayUpgradeStatus = function()
   {
   if (setting.sysd_sup.update)
      {
      _newtecProgressBar.render("upgradePercentComplete");
      _newtecProgressBar.set('value', Math.round(setting.sysd_sup.percent_complete));
      $("upgradeStartTime").innerHTML = setting.sysd_sup.start_time;
      $("upgradePercentLabel").innerHTML = setting.sysd_sup.percent_complete + "% Completed";
      $("newtecUpgradeRow").style.display = "";
      $("newtecVersionsRow").style.display = "none";
      setTimeout(DisplayUpgradeStatus, 2000);
      }
   else if ($("newtecVersionsTable").innerHTML == "")
      {
      DisplayNewtecVersions(setting.sysd_sup.file);
      }
   else
      {
      $("newtecUpgradeRow").style.display = "none";
      $("newtecVersionsRow").style.display = "";
      }
   }
   ;/*****************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file handles the upload functionalities
 *****************************************************************************/

var 
_putfilesCompleted = 0,


HasAdtecFeatureExtension = function(fileName)
   {
   return GetFileExtension(fileName).toLowerCase() == _ADTEC_FEATURE_EXT;
   },
IsDvcFilename = function(fileName)
   {
   return GetFileExtension(fileName).toLowerCase() == _ADTEC_DVC_EXT;
   },
   
IsAdtecFirmwareUpload = function(type, filename)
   {
   var regex = /[\w\/]+\.nfcms\.[tgz||zip]/i;
   return ((type=="application/x-compressed")&&(regex.test(filename)));
   },

OnPutUploadsStart = function()
   {
   $("resetUploadsImg").style.display = "none";
   $("putUploadTblHeader").style.display = "";
   _putfilesCompleted = 0;
   },
   
OnPutUploadsEnd = function()
   {
   $("resetUploadsImg").style.display = '';
   
   if((GetCurrentPageId()==_PAGE[_PAGEIDX.fmw].id) && _hasFirmwareUpload)
      {
      _uploadPanel.hide();
      GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);   
      }
   if(_hasFeatureUpload)
      {//refresh app to get list of updated features.
      location.reload(true);
      }
   if(_hasDemodProfile)
      {
      LoadDemodProfileList($("demodPrfManageSelect"));
      }
   
   _hasFirmwareUpload = _hasFeatureUpload = _hasDemodProfile = false; //reset flags
   },

OnPutResetStatus = function()
   {
   var len = $("putUploadTable").rows.length;
   for(var i= len-1; i>0; i--)
      {
      $("putUploadTable").deleteRow(i);
      _putfilesCounter--;
      }
   $("putUploadTblHeader").style.display = "none";
   $("resetUploadsImg").style.display = 'none';
   },
/*********************************************************************************************************************************************************
 * Displays File progress back to the user.
 *********************************************************************************************************************************************************/
PutFileProgress = function(progressEvent, idx)
   {
   if (progressEvent.lengthComputable) 
      {  
      var percentage = Math.round((progressEvent.loaded * 100) / progressEvent.total); 
      _putPbArr[idx].set('value',percentage);
      $("putPercTd"+idx).innerHTML = percentage + "%";  
      }
   },
   
/*********************************************************************************************************************************************************
 * Triggered when an error has been detected in the file uploaded.
 * IDX refers to the index of the file (see _putfilesCounter var)
 *********************************************************************************************************************************************************/
OnPutFileError = function(idx)
   {
   _putPbArr[idx].set('value',0);
   $("putPercTd"+idx).innerHTML = '0%';
   $("putStatusTd" + idx).style.color = _ADTCOLOR.RED;
   $("putStatusTd" + idx).innerHTML = '<b>Error!</b>';
   _putfilesCompleted++;
   if(_putfilesCompleted>=_putfilesCounter)
      {
      OnPutUploadsEnd();
      }
   },
   
/*********************************************************************************************************************************************************
 * Triggered when a file has completely uploaded.
 * IDX refers to the index of the file being uploaded (see _putfilesCounter var)
 *********************************************************************************************************************************************************/
OnPutFileComplete = function(idx)
   {
   _putPbArr[idx].set('value',100);
   $("putPercTd"+idx).innerHTML = "100%";
   $("putStatusTd" + idx).style.color = _ADTCOLOR.GREEN;
   $("putStatusTd" + idx).innerHTML = '<b>Complete</b>';
   _putfilesCompleted++;
   if(_putfilesCompleted>=_putfilesCounter)
      {
      OnPutUploadsEnd();
      }
   },
    
/*********************************************************************************************************************************************************
 * Returns TRUE if both the hardware, and the user's environment support uploading files using PUT.  
 * Returns FALSE otherwise.
 *********************************************************************************************************************************************************/
SupportsPutUpload = function()
   {
  
   var serverOk = function()
      { //Returns TRUE if Hardware supports PUT uploader
      return (IsEncoderUnit() ||  (GetProductId() == _PRODUCT.RD60.id) || (GetProductId() == _PRODUCT.EN20.id) );
      }; 
      
   var clientOk = function()
      {//Returns a function reference if browser supports PUT Uploader that JS interprets as TRUE.
       //Further testing is required to verify that this can safely be compared to undefined instead of returning a function. MT
      var x = new XMLHttpRequest();
      return (window.File && window.FileList && window.FileReader && (x.sendAsBinary || window.Uint8Array));
      };
   return serverOk() && clientOk();
   
   },
   
// Event handler.  On Put file drag hover  
PutFileDragHover = function(e) 
   {  
   e.stopPropagation();  
   e.preventDefault();  
   e.target.className = (e.type == "dragover")? "hover" : "";  
   },
   
//Uploads file using PUT Method
DoPutUpload = function(theFile, idx)
   {
   return function(e) 
      {
      var x = new XMLHttpRequest();
      x.onreadystatechange = function() 
         {
         if(this.readyState==4)
            {
            switch(this.status)
               {
               case 200:
               case 201:
               case 204: 
                  OnPutFileComplete(idx);
                  break;
               default:
                  OnPutFileError(idx);
               break;
               }
            }
         };
      var fn = theFile.fileName || theFile.name;
      
      var onProgress = function(progressEvent)
         {
         PutFileProgress(progressEvent, idx);   
         };
      x.upload.addEventListener("progress", onProgress, false);
      
      x.open('PUT', "/put?filename=" + fn, true);
      
      if(x.sendAsBinary)
         { //currently supported in FIREFOX 4+ only
         x.sendAsBinary(e.target.result);
         }
      else
         { //other HTML5 modern-browsers
         if(window.Uint8Array) //check is probably unnecessary.
            {
            try
               {
               var byteValue = function(myData){return myData.charCodeAt(0) & 0xff;}; //inline function to transform data
               var ords = Array.prototype.map.call(e.target.result, byteValue);
               var ui8a = new Uint8Array(ords);
               x.send(ui8a.buffer);
               }
            catch(err)
               {
               LogMyles("Upload Failed. Exception "+ err.description); //highly unlikely
               }
            }
         else
            {
            LogMyles("Upload Failed.  Data conversion to Uint8Array is not supported."); //highly unlikely
            }
         }
      };
   },


// Event Handler..  Triggered when user has selected file(s) to be uploaded.
PutFileSelectHandler = function (e) 
   {  
   _hasFirmwareUpload = _hasFeatureUpload = _hasDemodProfile = false;
   var addPutFileRow = function(count)
      {
      var row = document.createElement("tr");
      var fnCell = document.createElement("td");
      var pbCell = document.createElement("td");
      var percCell = document.createElement("td");
      var statusCell = document.createElement("td");
      var pbCont = document.createElement("div");
      row.id = "putRow" + count;
      fnCell.id = "putFnTd" + count;
      pbCell.id = "putPbTd" + count;
      percCell.id = "putPercTd" + count;
      pbCont.id = "pbCont" + count;
      statusCell.id = "putStatusTd" + count;
      $("putUploadTable").appendChild(row);
      row.appendChild(fnCell);
      row.appendChild(pbCell);
      row.appendChild(percCell);
      row.appendChild(statusCell);
      pbCell.appendChild(pbCont);
      };
   // cancel event and hover styling  
   PutFileDragHover(e);
   // fetch FileList object  
   var files = e.target.files || e.dataTransfer.files;
   // process all File objects  
   for (var i = 0; i<files.length; i++, _putfilesCounter++) 
      {  
      
      if(_putfilesCounter===0){OnPutUploadsStart();}
      var fn = files[i].fileName || files[i].name;
      if(HasAdtecFeatureExtension(fn))
         {
         _hasFeatureUpload = true;
         }
      else if(IsAdtecFirmwareUpload(files[i].type, fn))
         {
         _hasFirmwareUpload = true;
         }
      else if((GetProductId() == _PRODUCT.RD60.id) && (GetCurrentPageId()==_PAGE[_PAGEIDX.dem].id)&&(IsDvcFilename(fn)))
         {
         _hasDemodProfile = true;
         }
      
      var pbCfg = {"value": 0, "minValue": 0, "maxValue": 100, "width": 100, "height": 10};
      //prepare file progress table
      addPutFileRow(_putfilesCounter);
      _putPbArr[_putfilesCounter] = new YAHOO.widget.ProgressBar(pbCfg).render("pbCont"+_putfilesCounter);
      $("putFnTd"+_putfilesCounter).innerHTML =  fn;
      $("putPercTd"+_putfilesCounter).innerHTML = "0%";
      $("putStatusTd" + _putfilesCounter).style.color = _ADTCOLOR.GOLD;
      $("putStatusTd" + _putfilesCounter).innerHTML = '<b>Uploading</b>';
      
      
      var reader = new FileReader();
      reader.onload = DoPutUpload(files[i], _putfilesCounter); // Event handler when file is fully read.
      reader.readAsBinaryString(files[i]); //read file
      }  
   },  

/*
 * Prepares methods to handle PUT file upload operations.
 */
PreparePutUpload = function()
   {
   
   var fileselect = $("putFileSelect"), 
   filedrag = $("fileDrag");
   // file select  
   fileselect.addEventListener("change", PutFileSelectHandler, false);  
   // is XHR2 available?  
   var xhr = new XMLHttpRequest();  
   if (xhr.upload) 
      {  
      // file drop  
      filedrag.addEventListener("dragover", PutFileDragHover, false);  
      filedrag.addEventListener("dragleave", PutFileDragHover, false);  
      filedrag.addEventListener("drop", PutFileSelectHandler, false);  
//      filedrag.style.display = "block";  
      }  
   },
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/    
RenderUploadPanel = function()
   {
   //var effectObj = {};
   var panelConfig =  //set panel config properties
      {
      width:"500px",            
      iframe: false,
      autofillheight: "body", 
      fixedcenter: true, 
      constraintoviewport: true, 
      underlay:"matte",
      modal: false, 
      close:true, 
      visible:false, 
      draggable:true,
      xy: [0, 0]
      
      };
   
   _uploadPanel = new YAHOO.widget.Panel("uploadPanel", panelConfig); //create uploadPanel
   _uploadPanel.setHeader("Adtec Digital Uploader");
   if(SupportsPutUpload())
      {
      var markup = ''
         + '<form id="putUpload" >'  
            + '<fieldset>'  
//               + '<legend>HTML File Upload</legend>'  
//               + '<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />'  
               + '<div>'  
//                  + '<label for="fileSelectLbl">Files to upload:</label>'  
                  + '<input type="file" id="putFileSelect" name="fileselect[]" multiple="multiple" />'  
                  + '<div id="fileDrag" style="display:none">or drop files here</div>' 
                  + '<a id="resetUploadsImg" href="javascript:OnPutResetStatus();" style="display:none;"><img src="/images/clear.gif" /></a>'
               + '</div>'  
            + '</fieldset>'  
         + '</form>'  
         + '<table id="putUploadTable"><tr id="putUploadTblHeader" style="display:none"><th>Filename</th><th>Completed</th><th>%</th><th>Status</th></tr></table>'
         +'<br />&nbsp;<br />&nbsp'
         ;
      _uploadPanel.setBody(markup); //write ftp upload applet
      _uploadPanel.render();//render
      PreparePutUpload();
      }
   else
      { /*legacy java applet uploader
      var msgStr = ""
         + "Our latest features may not be supported by your current browser." 
         + "For a better experience, and to take advantage of the latest HTML5 features, we recommend upgrading your browser." 
         + "See our spec sheet for a list of fully supported Browsers.";
      alert(msgStr); //TODO: Activate alert when the list of supported browsers has been determined, and placed in the spec sheet and/or user's manual.*/
      
      var XHRCallback =
         {
         success: function(o)
            {
            _uploadPanel.setBody(o.responseText); //write ftp upload applet
            _uploadPanel.render();//render
            },
               
         failure: function(o)
            {
            LogMyles("FTP Upload could not be instantiated");
            }
         };
         
         
      var postdataObj = 
         {
         id: _REQID.GETFTPMARKUP, 
         req:Math.random()
         }; //build post arguments object
      var postdataStr = _yuiStringify(postdataObj); //transform object to string 
      ConnectToReqHandler(XHRCallback, postdataStr);
      }
         
   },

   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
ShowUploader = function()
   {
   _uploadPanel.show();
   },
   
/*********************************************************
 * Event Handler when the FTPUpload has been completed. 
 * This function is externally invoked by the FTPUpload
 * java applet.  Keep this in mind when/if renaming this function.
 ********************************************************/
OnFTPUploadComplete = function()
   {
   _uploadPanel.hide();
   if(GetCurrentPageId()==_PAGE[_PAGEIDX.fmw].id)
      {
      GetVersions(_REQID.GETUNINSTALLEDFIRMWARE);   
      }
   }
   ;
   
/*****************************************************************************
 * @file
 * @author  Original:      N/A
 * @author  Contributors:  German Escallon
 * @date    Created:       N/A
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file handles the different utilities needed in Adtec's user 
 * interfaces
 *****************************************************************************/

var 
/*
 * Returns TRUE if the client is using a supported mobile device.  False othewise
 */
IsMobile = function()
   {
   var result = false;
   switch(navigator.platform)
      {
      case "iPad":
      case "iPhone":
      case "iPod":
         result = true;
         break;
      case "Win16":
      case "Win32":
      case "Win64":
      case "MacPPC":
      case "MacIntel":
      case "PLAYSTATION 3":
         result = false;
         break;
      default: 
         result = false;
         break;
         
      }
   return result;
   },
/********************************************************************
*  converts from decimal to hex
*  arg[0], string containing number in decimal format
*  returns string in hex value 
********************************************************************/
DecToHex = function
   (
   strDecimal
   )
   {
   var hex = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
   var intDecimal;
   if(!isNaN(intDecimal = parseInt(strDecimal, _DEFAULT_NUM_BASE))) //parse into int
      {
      var str = "";
      while(intDecimal>=16) ////TODO: replace magic value
         {
         str += hex[intDecimal%_HEXNUMBASE]; //remainder //TODO: replace magic value
         intDecimal = Math.floor(intDecimal/_HEXNUMBASE); //TODO: replace magic value
         }
      str += hex[intDecimal]; //attach last digit
      return (ReverseString(str)); //Success. Reverse result and return. 
      }
   else
      {
      LogMyles("DecToHex error.  The argument is not a valid decimal number");
      return _DEFAULT_ERROR_VAL; 
      }
      
   }, 
/********************************************************************
*  converts from HEX to Decimal format
*  arg[0], string containing number in hex format
*  returns string in dec value 
********************************************************************/   
HexToDec = function
   (
   pHex
   )
   { 
   pHex = "" + pHex; //turn to string in case an int is passed to it.
   var i;
   //Removes leading prefix '0x' if it exists
   if( (pHex.indexOf(_HEX_PREFIX)===0) || (pHex.indexOf(_HEX_PREFIX.toUpperCase())===0) ) { pHex = pHex.substring(_HEX_PREFIX.length, pHex.length); } 
   
   var hex = pHex.toUpperCase(); //transform to upper case characters, establishing a common format
   var hexString = "0123456789ABCDEF";
   var result = 0; //initialize result variable
   
   
   for( i=0; i<hex.length; i++) //validate input
      {
      //Verify that there are no invalid characters in input
      if(hexString.indexOf(hex.charAt(i))==-1) 
         {
         LogMyles("HexToDec error.  The argument " + pHex + " is not a valid HEX number: " + hex.charAt(i));
         return _DEFAULT_ERROR_VAL;
         }
      }
   
   
   for( i=1; hex.length>0; i*=_HEXNUMBASE)
      {
      var temp = hexString.indexOf(hex.charAt(hex.length-1)) * i;
      result += temp;
      hex = hex.substring(0, hex.length-1); //removes last character
      } 
   return result;
   }, 

  
/********************************************************************
Reverses the given string.
********************************************************************/ 
ReverseString = function
   (
   str
   )
   {
   var N = str.length;
   var result = "";
   for(var i=0; i< N; i++) { result += str.substring(N-i-1, N-i); }
   return result;
   }, 





/*******************************************************************
Verifies that string containing time is valid.
********************************************************************/
IsTime = function
   (
   time
   )
   {
   
   var HOUR_POS =             0;
   var MINUTE_POS =           1;
   var SECOND_POS =           2;
   var MAX_TIME_ARRAY_LEN =   3;
   
   var timeArray = [];
   timeArray = time.split(_TIME_DELIM);
   if(timeArray.length != MAX_TIME_ARRAY_LEN) { return false ; } //invalid format  
   var hh = parseInt(timeArray[HOUR_POS], _DEFAULT_NUM_BASE); //hours 
   var mm = parseInt(timeArray[MINUTE_POS], _DEFAULT_NUM_BASE); //minutes 
   var ss = parseInt(timeArray[SECOND_POS], _DEFAULT_NUM_BASE); //seconds 
   
   if(hh < 0 || hh > _MAXHOUR ) { return false; } //invalid # of hours 
   if(mm < 0 || mm > _MAXMINUTE ) { return false; } //invalid # of minutes 
   if(ss < 0 || ss > _MAXSECOND ) { return false; } //invalid # of seconds 
   
   return true; //valid time
   
   }, 


/******************************************************
* converts date formatting from mm/dd/yyyy (Standard)  to mm/dd/yy (Adtec API)
*******************************************************/
ToMMDDYY = function
   (
   strDate
   )
   {
   
   var strYY, yy;
   var strYYYY = strDate.substring(strDate.lastIndexOf("/")+1); //get year in string format
   var yyyy = parseInt(strYYYY, _DEFAULT_NUM_BASE); //convert year to int
   if(yyyy<_Y2KVAL) { yy = yyyy-_Y2KVAL-_YEARSINCENTURY; } //1930 - 1999 
   else {  yy = yyyy-_Y2KVAL; } //2000 - 2030 
   if(yy<10) { strYY = "0" + yy; } //add trailing zero and convert to string 
   else { strYY = '' + yy; } //convert to string w/out trailing zero 
   
    
   return strDate.replace(strYYYY, strYY); // return date in mm/dd/yy format (Adtec API)
   
   }, 



/******************************************************
* converts date formatting from mm/dd/yy (Adtec API) to mm/dd/yyyy (standard)
*******************************************************/
ToMMDDYYYY = function
   (
   strDate
   )
   {
   
   var mm_dd = strDate.substring(0, strDate.lastIndexOf("/")); //extract mm and dd substring
   
   var yyyy; 
   var strYY = strDate.substring(strDate.lastIndexOf("/")+1); //get year in string format
   var yy = parseInt(strYY, _DEFAULT_NUM_BASE); //convert str to int
   if(yy<_Y2KTHRESHOLD) { yyyy = yy+_Y2KVAL; } //year is between 2000 and 2029
   else { yyyy = yy + (_Y2KVAL-_YEARSINCENTURY); } //year is between 1930 and 2000
   
   
   return mm_dd + "/" + yyyy; //return reformatted string
   }, 



/******************************************************************
* Removes leading whitespaces from strings 
********************************************************************/ 
LTrim = function
   ( 
   value 
   ) 
   {
   if(value===undefined){value = "";} else if(value===null || value.length===0 ) { value= "" ;}
   var re = /\s*((\S+\s*)*)/;
   return value.replace(re, "$1");
   
   }, 

/******************************************************************
* Removes trailing whitespaces from strings
********************************************************************/
RTrim = function
   ( 
   value 
   ) 
   {
   
   var re = /((\s*\S+)*)\s*/;
   return value.replace(re, "$1");
   
   },

/******************************************************************
* Removes leading and trailing whitespaces from strings
********************************************************************/
Trim = function
   ( 
   value 
   ) 
   {
   if(value===undefined){value = "";} else if(value===null || value.length===0 ) { value= "" ;}
   return RTrim(LTrim(value));
   },
 
 
/******************************************************************
* Removes quotes from strings
********************************************************************/
RemoveQuotes = function
   (
   value
   )
   {
   var result = Trim(value);
   return result.substring(1, result.length - 1);
   },

/******************************************************************
* Converts bytes into MB
********************************************************************/
BytesToMB = function
   (
   inMB
   )
   {
   var intBytes = parseInt(inMB, _DEFAULT_NUM_BASE);
   var floatMB = intBytes / _MILLION;  //TODO: replace magic values
   var result = floatMB + '';
   var MAX_DECIMAL_LEN = 2;

   if(result.lastIndexOf(".")!=-1)
      {//TRUNCATES DECIMALS.
      var decimal = result.substring(result.lastIndexOf(".")+1); 
      if (decimal.length > MAX_DECIMAL_LEN) {decimal = decimal.substring(0, MAX_DECIMAL_LEN);} 
      result = result.substring(0, result.lastIndexOf(".")) + "." + decimal; 
      }
   else
      {
   result +=".00";
      }
   return result;
   },
   
   
/*******************************************************************
* This function accepts a string variable and verifies if it is a
* proper date or not. It validates format matching either
* mm-dd-yyyy or mm/dd/yyyy. Then it checks to make sure the month
* has the proper number of days, based on which month it is.
*
* The function returns a date code indicating the error found (if any), 
* or _DATERESULT.OK if test succeeds.
********************************************************************/
IsDate = function
   (
   dateStr
   )
   {

   var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
   var matchArray = dateStr.match(datePat); // is the format ok?

   if (matchArray === null) 
      {
      return _DATERES.INVALIDFORMAT;
      }

   var month = parseInt(matchArray[1],_DEFAULT_NUM_BASE); // parse date into variables 
   var day = parseInt(matchArray[3],_DEFAULT_NUM_BASE);
   var year = parseInt(matchArray[5],_DEFAULT_NUM_BASE);

   if (month < _MINMONTHSINYEAR || month > _MAXMONTHSINYEAR) //TODO: Replace magic values 
      { // check month range
      return _DATERES.INVALIDMONTH;
      }  

   if (day < _MINDAYSINMONTH || day > _MAXDAYSINMONTH) //TODO: Replace magic values
      {
      return _DATERES.INVALIDDAY;
      }

   if(_MAXDAYSINMONTHARR[parseInt(month, _DEFAULT_NUM_BASE)]<day)
      {
      return _DATERES.INVALIDDAYSINMONTH;   
      }
   

   if (month == _MONTH.FEBRUARY)   
      { // check for february 29th in a non-leap year
      var isleap = (year % _STDLEAPYRFREQUENCY === 0 && //every four years february 29th is a valid day
         (year % _YEARSINCENTURY !== 0 || year % (_YEARSINCENTURY*4) === 0)); //exception to gregorian calendar.  Years 2100, 2200, 2300 are not a leap years, but 2000 and 2400 are.  
      if (day > _MAXDAYSINFEBRUARY || (day==_MAXDAYSINFEBRUARY && !isleap)) 
         {
         return _DATERES.INVALIDDAYSINFEB;
         }
      }

   return _DATERES.OK;//date is valid

   },



/***************************************************************
* The VerifyIp validates ip addresses in the format xxx.xxx.xxx
* based on script found on http://javascript.internet.com
* original comments left intact
***************************************************************/

/*
<!-- Original:  Jay Bienvenu -->
<!-- Web Site:  http://www.bienvenu.net -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

*/

   
VerifyIP = function
   (
   ipaddr 
   )
   {
   var MAX_IP_SECTION_VAL = 255;
   ipaddr = Trim(ipaddr);
   if (_IPREGEX.test(ipaddr)) 
      {
      var parts = ipaddr.split(".");
      for (var i=0; i<parts.length; i++) 
         {
         if (parseInt(parseFloat(parts[i]), _DEFAULT_NUM_BASE) > MAX_IP_SECTION_VAL) { return false; }
         }
      return true;
      } 
   else 
      {
      return false;
      }
   },


/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
Pause = function
   (
   pDuration
   )
   {
   var duration = pDuration*_MILISECONDSPERSECOND;
   var done = false;
      
   if((duration===null)||(duration===0)) { return ; }
   var futureTime = (new Date()).getTime() + duration;
   
   while(!done)
      {
      var currTime = (new Date()).getTime();
      if(currTime > futureTime) { done = true; }
      }
   },
   
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
GetCurrentTime = function()
   {  
      
      
   var month, day, year, hour, minute, second;
   
   var date = new Date();
   month = date.getMonth() + 1;
   day = date.getDate();
   hour = date.getHours();
   minute = date.getMinutes();
   second = date.getSeconds();
   year = date.getFullYear();
   
   year = '' + year;
   year = year.substring(2); 
   
   return (month + "/" + day + "/" + year + " at " + hour + _TIME_DELIM + minute + _TIME_DELIM + second);
      
       
   },
   
GetCurrentTimestamp = function()
   {  
   var month, day, year, hour, minute, second;
   
   var date = new Date();
   month = date.getMonth() + 1;
   day = date.getDate();
   year = date.getFullYear();
   hour = date.getHours();
   minute = date.getMinutes();
   second = date.getSeconds();
   if(month<10)   {month = "0" + month;}
   if(day<10)     {day = "0" + day;}
   if(year<10)    {year = "0" + year;}
   if(hour<10)    {hour = "0" + hour;}
   if(minute<10)  {minute = "0" + minute;}
   if(second<10)  {second = "0" + second;}
   
   return (month + "" + day + "" + year + "_" + hour + "" + minute + "" + second);
   },


IsValidHex = function
   (
   entry
   )
   {
   var validChars='0123456789ABCDEF';// characters allowed in hex
   
   if((entry.substring(0, 2)=="0x")||(entry.substring(0, 2)=="0X"))
      {
      entry = entry.substring(2); //remove prefix
      }
   
   var strlen=entry.length;         // how long is test string
   if(strlen <1)   {  return false;  } //empty string
   
   // Now scan string for illegal characters
   for (var i=0;i<strlen;i++)
      {
      if(validChars.indexOf(entry.charAt(i))<0)  {  return false;  } //invalid character found
      } // end scanning loop
   return true; //string is a valid hex
   },
   

/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/ 
HHMMSSToMiliseconds = function
   (
   hhmmssStr
   )
   {
   var numMiliseconds = 0;
   var hhmmssRegex = /^\s*\d{1,2}:\d{1,2}:\d{1,2}\s*$/;
   if(hhmmssRegex.test(hhmmssStr))
      {
      var hhmmssArr = Trim(hhmmssStr).split(_TIME_DELIM);
      
      numMiliseconds = 
         (parseInt(hhmmssArr[0], _DEFAULT_NUM_BASE)* _MILISECONDSPERHOUR) + 
         (parseInt(hhmmssArr[1], _DEFAULT_NUM_BASE)* _MILISECONDSPERMINUTE) +
         (parseInt(hhmmssArr[2], _DEFAULT_NUM_BASE)* _MILISECONDSPERSECOND) 
         ;
      }
   else
      {
      numMiliseconds = _INVALID_DURATION_IN_MSECS; //return ERROR
      }
   return numMiliseconds;
   },
   
   
/************************************************************
 * Transforms a string representing a number in miliseconds into 
 * a date string in the format HH:MM:SS.
 * 
 * @return           The number of miliseconds in HH:MM:SS representation
 *                   or "--" in case of error.
 ***********************************************************/   
MilisecondsToHHMMSS = function
   (
   milisecondsStr
   )
   {
   
   var ms = parseInt(milisecondsStr, _DEFAULT_NUM_BASE);
   if(isNaN(ms))
      {
      
      return '--';
      }
   else
      {
      var time = [];
      //get hours
      time[0] = Math.floor(ms / _MILISECONDSPERHOUR); 
      ms %= _MILISECONDSPERHOUR;
      
      //get minutes
      time[1] = Math.floor(ms / _MILISECONDSPERMINUTE); 
      if(time[1] < 10) {   time[1] = "0" + time[1];   }
      ms %= _MILISECONDSPERMINUTE;
      
      //get seconds
      time[2] = Math.floor(ms/_MILISECONDSPERSECOND);
      if(time[2] < 10) {   time[2] = "0" + time[2];   }
      
      return time.join(_TIME_DELIM); 
      }
   }, 

/********************************************************************************************
 * Accepts a filepath as input (e.g /media/hd0/media/filename.ext), 
 * and returns only the basename (filename), stripping out the path and extension (if any) 
********************************************************************************************/
GetFileBasename = function
   (
   fpath
   )
   {
   var filepath = Trim(fpath); //removes white space surrounding filepath 
   var result='';
   var lastSlashInx = (filepath.lastIndexOf("/") >=0)? filepath.lastIndexOf("/"): filepath.lastIndexOf("\\");
   var lastDotInx = filepath.lastIndexOf(".");
   
   if(lastSlashInx==-1)
      {//no path given
      
      if(lastDotInx==-1)
         {//no extension or path given. 
         result = filepath;    
         }
      else
         {//strip out extension
         result = filepath.substring(0, lastDotInx) ;  
         }
      }
   else
      {//strip out path
      if(lastDotInx==-1)
         {//no extension. Strip out path
         result = filepath.substring(lastSlashInx+1);      
         }
      else
         {//strip out path and extension
         result = filepath.substring(lastSlashInx+1, lastDotInx);                        
         }
      }
   
   return result;
   
   },

/********************************************************************************************
 * Accepts a filepath as input (e.g /media/hd0/media/filename.ext), 
 * and returns only the extension (ext), stripping out the path and filename (if any) 
********************************************************************************************/
GetFileExtension = function
   (
   filepath
   )
   {
   if((filepath===undefined) ||(filepath===null) )
      {
      LogMyles("GetFileExtension Error: Invalid argument.");
      return undefined;
      }
   var lastDotInx = filepath.lastIndexOf(".");
   
   if(lastDotInx==-1)
      {//no extension given
      return ''; //returns empty string
      }
   
   return filepath.substring(lastDotInx+1);    
   
   },

/********************************************************************************************
 * Accepts a filepath as input (e.g /media/hd0/media/filename.ext), 
 * and returns the full filename, including the extension but stripping out the path. (e.g filename.ext) 
********************************************************************************************/
GetFilename = function
   (
   fpath
   )
   {
   return GetFileBasename(fpath) + "." + GetFileExtension(fpath);   
   },

/********************************************************************************************
 * Accepts a filepath as input (e.g /media/hd0/media/filename.ext), 
 * and returns only the path (/media/hd0/media), stripping out the filename and extension (if any) 
********************************************************************************************/
GetPathToFile = function
   (
   filepath
   )
   {
   var lastSlashInx = filepath.lastIndexOf("/");
   
   if(lastSlashInx==-1)
      {//no path given
      return ''; //returns empty string
      }
   
   return filepath.substring(0, lastSlashInx);    
   },

  
/***************************************************************************************************************
 * TODO: Doc?
 **************************************************************************************************************/
DomSelectReset = function
   (
   selectObj
   )
   {
   if((selectObj!==null)&&(selectObj!==undefined)&&(selectObj.length>0))
      {
      for(var i =selectObj.length; i>=0; i--)
         {
         selectObj.remove(i);
         }      
      }
   },   

/*********************************************************************
 * 
 * Returns the number of rows in the given table (<tr>) element.
 * 
 *********************************************************************/   
DomTableGetNumRows = function(tableObj)
   {
   if(GetBrowserType()==_BROWSER.IE)
      {
      var trRegex = /<\s*tr\s*/igm;
      var myStr = tableObj.innerHTML;
      var matches = (myStr).match(trRegex); //ugly quick patch to bug in IE 8+.  Searches the innerHTML for number of rows.
      if(matches===null){matches = [];}
      var result = matches.length;
      return result;
      }
   return tableObj.rows.length;
   },
   
/*********************************************************************
 * Clears the given Table element by eliminating all of its existing rows.
 *********************************************************************/
DomTableClear = function(tableObj)
   {
   var numRows = DomTableGetNumRows(tableObj);
   for(var i=numRows -1; i>=0; i--)
      {
      tableObj.deleteRow(i);
      }
   },


/*******************************************
 * Returns the maximum number of days for a given 
 * month/year combination.  
 * 
 * Note:  Leap years are taken into account, so 2/29/16 is valid, whereas 2/29/2011 is NOT
 ******************************************/
MaxDaysInMMYY = function
   (
   month, 
   year
   )
   {
   if(isNaN(month) || isNaN(year)) //invalid arguments
      {
      return -1;
      }      
   if(
      (month < _MINMONTHSINYEAR)|| //invalid month
      (month > _MAXMONTHSINYEAR)||
      (year  < _MINYY)|| //invalid year
      (year  > _MAXYY)
     )
      {
      return -1;
      }
   
   
   var result = _MAXDAYSINMONTHARR[month];
   if (
         (month == 2) &&               // If February in a 
         ((year % 4) !== 0)               // non-leap year,
      )    
      {
      result--;                  // Not 29 days, but 28 
      }
   
   return result;
   }, 
   
   
/**********************************************************************************************
 * Receives a Date Object <javascript> input, and returns a string representing such object
 * in a MM/DD/YYYY HH:MM:SS format for easy human interpretation   
**********************************************************************************************/
DateObjToDateTimeStr = function
   (
   dateObj
   )
   {
   var month, day, year, hour, minute, second;
   month =  (dateObj.getMonth()<10)? "0" + dateObj.getMonth() : dateObj.getMonth();
   day =    (dateObj.getDate()<10)? "0" + dateObj.getDate() : dateObj.getDate();
   year =   dateObj.getFullYear();
   hour =   (dateObj.getHours()<10)? "0" + dateObj.getHours() : dateObj.getHours();
   minute = (dateObj.getMinutes()<10)? "0" + dateObj.getMinutes() : dateObj.getMinutes();
   second = (dateObj.getSeconds()<10)? "0" + dateObj.getSeconds() : dateObj.getSeconds();    
   return month + "/" + day + "/" + year + " " + hour + _TIME_DELIM + minute + _TIME_DELIM + second;    
   },

 
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/
SetCursorWait = function
   (
   timeout
   )
   {
   ResetCursor();
   if((timeout===undefined)||(timeout===null)||(isNaN(parseInt(timeout, 10)))||(parseInt(timeout, 10)<0))
      {
      timeout = _DEFAULT_CURSOR_WAIT_TIMEOUT;
      }
   document.body.style.cursor = "wait";
   _waitTimeout = setTimeout(ResetCursor, timeout);
   },
   
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/
ResetCursor= function()
   {
   clearTimeout(_waitTimeout);
   document.body.style.cursor = "";
   },
   
   /***************************************************************************************************************
    * TODO: Doc?
    **************************************************************************************************************/
Upconvert = function
   (
   input, //decimal integer. Number to be upconverted
   divisor, //decimal integer.  Divisor
   precision //Decimal integer.  a.k.a number of digits
   )
   {
   var result = parseFloat(input/divisor);
   if(!isNaN(result))
      {
      result = result + ""; //convert from float to a string.
      }
   else
      {
      //TODO: Log error
      return result;
      }
   
   return parseFloat(result);
   },


/******************************************************************************************
 * Retrieves information about the browser being used by the client to access the Web UI 
 ******************************************************************************************/
GetBrowserType = function()
   {
   var result = _BROWSER.UNKNOWN;
   
   switch(navigator.appName.toUpperCase())
      {
      case "NETSCAPE": //firefox, chrome, safari
         switch(navigator.appCodeName.toUpperCase())
            {
            case "MOZILLA":
               result = _BROWSER.MOZILLA;
               break;
               
            case "SAFARI": //TODO: Test
               result = _BROWSER.SAFARI;
               break;
            case "CHROME": //TODO: Test
               result = _BROWSER.CHROME;
               break;
            default: 
               result = _BROWSER.NETSCAPE;
            break;
            }
         break;
         
      case "MICROSOFT INTERNET EXPLORER":    
         result = _BROWSER.IE;
         break;
      case "OPERA":
         result = _BROWSER.OPERA;
         break;
      case "KONQUEROR":
         result = _BROWSER.KONQUEROR;
         break;
      }

   return result;
   },

   
/***********************************************************************************************
 * Returns TRUE if the currently selected option on the argument (a DOM SELECT object)  is disabled.
 * Returns FALSE otherwise
 **********************************************************************************************/
DomSelectCurrOptionIsDisabled = function(selectObj)
   {
   var result = true;
   if((selectObj.selectedIndex>=0) && (selectObj.selectedIndex<selectObj.options.length))
      {
      result = selectObj.options[selectObj.selectedIndex].disabled;
      }
   return result;
   },

/***********************************************************************************************
 * Automatically selects the first option that is not disabled from the  argument (a DOM SELECT object)  
 * No action if there are no available options.
 **********************************************************************************************/
DomSelectSetFirstAvailableOption = function(selectObj)
   {
   for(var i=0; i<selectObj.length; i++)
      {
      if(!selectObj.options[i].disabled)
         {
         selectObj.selectedIndex = i;
         break;
         }
      }
   
   return;
   },
   
/***********************************************************************************************
 * Returns TRUE if the given value corresponds to a valid option in the given select object.
 * Returns FALSE otherwise
 **********************************************************************************************/   
DomSelectHasValue = function(selectObj, val)
   {
   val = "" + val; //from int to string.
   var result = false; //set to false by default
   for(var i=0; i<selectObj.length; i++)
      {
      if(selectObj.options[i].value == val)
         {
         result = true;
         break;
         }
      }
   return result;
   },
   
/**************************************************************************************************
 * Checks if the given select object value is disabled. If it isn't no action is performed.
 * Otherwise, proceeds to set the first available value on the dropdown list.
 * Returns TRUE if the value has been changed.  False otherwise.
 *************************************************************************************************/
DomSelectSetFirstIfDisabled = function (selectObj)
   {
   var result = false;
   if (DomSelectCurrOptionIsDisabled(selectObj))
      {
      DomSelectSetFirstAvailableOption(selectObj);
      result = true;
      }
   return result;
   },
   
/**************************************************************************************************
 * Disables all options in the SELECT object being passed as an argument.
 *************************************************************************************************/
DomSelectDisableAll = function(selectObj)
   {
   for(var i=0; i<selectObj.length; i++)
      {
      selectObj.options[i].disabled = true;
      }
   },
   
/**************************************************************************************************
 * Enables all options in the SELECT object being passed as an argument.
 *************************************************************************************************/
DomSelectEnableAll = function(selectObj)
   {
   for(var i=0; i<selectObj.length; i++)
      {
      selectObj.options[i].disabled = false;
      }
   },

/**************************************************************************************************
 * Enables the option containing the value specified as the second parameter.
 *************************************************************************************************/
DomSelectEnableOptionByVal = function(selectObj, val)
   {
   val = '' + val;  //transforms (if needed) from int to string.
   for(var i=0; i<selectObj.length; i++)
      {
      if(selectObj.options[i].value == val)
         {
         selectObj.options[i].disabled = false;
         break;
         }
      }
   },
/**************************************************************************************************
 * Enables the option containing the value specified as the second parameter.
 *************************************************************************************************/
DomSelectDisableOptionByVal = function(selectObj, val)
   {
   val = '' + val;  //transforms (if needed) from int to string.
   for(var i=0; i<selectObj.length; i++)
      {
      if(selectObj.options[i].value == val)
         {
         selectObj.options[i].disabled = true;
         break;
         }
      }
   },
   
/****************************************************************
 * Disables the given DOM element.
 ****************************************************************/
DomDisableEL = function(el)
   {
   if((el!==undefined) && (el!==null) &&(el.style !== undefined)&& (el.style.display !== undefined))
      {
      el.disabled = true;
      }
   },

DomDisableEls = function(elArr)
   {
   for(var i=0; (elArr.length && (i<elArr.length)); i++)
      {
      DomDisableEL(elArr[i]);
      }
   },
/****************************************************************
 * Enables the given DOM element.
 ****************************************************************/
DomEnableEL = function(el)
   {
   if((el!==undefined) && (el!==null) && (el.style !== undefined)&& (el.style.display !== undefined))
      {
      el.disabled = false;
      }
   },
   
DomEnableEls = function(elArr)
   {
   for(var i=0; i<elArr.length; i++)
      {
      DomEnableEL(elArr[i]);
      }
   },   
/****************************************************************
 * Hides the given DOM element.
 ****************************************************************/
DomHideEl = function(el)
   {
   if((el!==undefined) && (el!==null)&& (el.style !== undefined)&& (el.style.display !== undefined))
      {
      el.style.display = "none";
      }
   },

/****************************************************************
 * Shows the given DOM element.
 ****************************************************************/
DomShowEl = function(el)
   {
   if((el!==undefined) && (el!==null) && (el.style !== undefined)&& (el.style.display !== undefined))
      {
      el.style.display = ""; 
      }
   },


/**********************************************************
 * Returns whether a param is an integer or not.
 * @return true:  The given param is an integer number. 
 * @return false: The given param is NOT an integer number.
 **********************************************************/
IsInt = function(inp)
   {
   return (inp.toString().search(/^-?[0-9]+$/) === 0);
   },
   

/******************************************************************************
 * Returns TRUE if the given string represents a hex number.  FALSE otherwise.
 *******************************************************************************/
IsHex = function(str)
   {
   var regex = /^\s*[0x]*[1-9a-fA-F]+\s*$/i;
   return regex.test(str);
   },


/*******************************************************
 * Given a string, it will return a similar string 
 * that can be used as a valid property or variable name
 ********************************************************/
ToValidVarName = function(rawStr)
   {
   var result = '';
   var regex = /[0-9a-zA-Z_$]/;
   var vRegex = /^[a-zA-Z_\$][0-9a-zA-Z_\$]*$/;
   for(var i=0; i<rawStr.length; i++)
      {
      if(regex.test("" + rawStr.charAt(i)))
         {
         result += rawStr.charAt(i);
         }
      else
         { //replace any invalid characters w/ an underscore
         result += "_";
         }
      }
   if(!vRegex.test(result))
      { //property cannot start w/ numbers
      result = "_" + result;
      }               
   return result;
   },

   
/*******************************************************************************
 * Removes consecutive white spaces and end of the line characters from input
 * string
 ******************************************************************************/
CleanupString = function(str)
   {

   var result = str;
   var done=false; //flag
   if(result.indexOf("\n")!=-1) { result = result.replace("\n", " "); } //strip newline characters
   while(!done)
      {  done = true; //reset flag
      if(result.indexOf("  ")!=-1)//look for consecutive space charcters
         {
         done = false; //force one more loop iteration
         result = result.replace("  ", " ");  //trim consecutive space characters
         }
      } //elihw

   return Trim(result);
   },
   
AddLeftPadding = function(val, ch, strMinLen)
   {
   var result = "" + val;
   if(isNaN(strMinLen))
      {
      strMinLen = 4;
      }
   while(result.length <strMinLen)
      {
      result = "" + ch + result;
      }
   return result;
   
   },
/*
 * Returns TRUE if the object passed is an aaray.
 * Returns FALSE otherwise
 */
IsArray = function(obj) 
   {
   return obj && 
        typeof obj === 'object' && 
        typeof obj.length === 'number' &&
        !(obj.propertyIsEnumerable('length'));
   },

GenerateRandomId = function(len)
   {
   var result = 'randId';
   var chars= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
   for(var i=0; i<3; i++)
      {
      result += chars[Math.floor((Math.random()*chars.length))];
      }
   while(($(result)!==null)&&($(result)!==undefined)){result += chars[Math.floor((Math.random()*chars.length))];   }
   return result;
   },

   
// Returns true if the HTML5 canvas feature is supported by the browser.  Returns false otherwise 
IsCanvasSupported = function()
   {
   var canvas =document.createElement("canvas"); 
   return canvas.getContext;
   }
   ;
   

   






   /*****************************************************************************
 * @file
 * @author  Original:      German Escallon
 * @author  Contributors:  N/A
 * @date    Created:       2008/12/29
 * @date    Last Edit:     $Date$ by $Author$
 * Description: This file handles the FEATURES subtab, under UPGRADE.
 *****************************************************************************/ 
/****************************************************************************************************
 *                                    FEATURES TAB Global Constants.
 *
 * NOTE:  const Keyword is not supported by Internet Explorer. Thus var is used instead.  
 * Treat these variables as #define's (in C/C++ code terms) and (even though its possible)  DO NOT 
 * re-assign any value to them at run time.                                            
****************************************************************************************************/
var 
   _FEATURES_LOAD_DEF_TIMEOUT = 3000,
   _PERM_KEY_VAL = 9999 //Warning..  Must be in sync w/ API 
;



var

/***********************************************************************************************************
 * Builds and renders the HTML Markup code for the FEATURES Tab
 ***********************************************************************************************************/
RenderFeatures = function()
   {
   var featuresHTML = ''
      + ' <h3>Features</h3>'
      + '<br /><b>Serial:</b><span id="prodSerialSpan"></span><br />'
      + '<br /><b>Product ID:</b><span id="prodIdSpan"></span><br />'
      + '<br /><span id="tempFeaIdSpan"></span><br />'
      ;
   
   if(SupportsDiagnosticsDownload())
      {
      // Diagnostic Package Button
      featuresHTML += ''
         + '<br /><a id="dwDiagnosticsLink" onclick="return DownloadDiagnostics();"><img src="/images/diagnosticpkg.gif"/></a><br />'
         ;
      }
   
   if(SupportsBoardsInfo())
      {
      featuresHTML += '<br /><b>BOARDS INFO</b><br /><div id="bidDtDiv"></div>';
      }
   
   featuresHTML += ''
      + '<br /><div id="featuresDatatable"></div>'
      ;
   if(GetProductId()==_PRODUCT.RD60.id) 
      {
      if(HasNewtecDemod()) 
         {
         featuresHTML += ''
            + '<br />Premium Demodulator ID: <span id="BoardIDSpan"></span><br /><br />'
            + '<table class="tunerTable">'
            + '<tr><th>Key ID</th><th>Description</th><th>Action</th></tr>'
            + '<tr><td><center><span id="BoardSetSpan"></span></center></td><td><center><span id="keyDescriptionSpan"></div></center></td><td><center><img src="/images/inputkey.gif" onClick="GetTunerKey();"/></center></td></tr>'
            + '</table>'
            ;
         }
     }
     if( IsENXX() && IsNtModSupported())
     {
        featuresHTML += ''
      + '<br />Modulator ID: <span id="BoardIDSpan"></span><br /><br />'
      + '<table class="tunerTable">'
      + '<tr><th>Key ID</th><th>Description</th><th>Action</th></tr>'
      + '<tr><td><center><span id="BoardSetSpan"></span></center></td><td><center><span id="keyDescriptionSpan"></div></center></td><td><center><img src="/images/inputkey.gif" onClick="GetTunerKey();"/></center></td></tr>'
      + '</table>'
      ;
   }
     featuresHTML += ''
      +  '<br /><br /><br />To purchase a key for one of your disabled features, contact your Adtec Digital Sales Representative. <br /><br />'
      +  '<b>Domestic Sales:</b>  Phone 1.615.256.6619  Fax 1.615.256.6593  <a href="mailto:sales@adtecinc.com">sales@adtecinc.com</a><br /><br />'
      +  '<b>International Sales:</b>  Phone +1 (904) 394-0389   Fax +1 (904) 421-0684 <a href="mailto:intlsales@adtecinc.com">intlsales@adtecinc.com</a><br /><br />'
      +  '<div id="feaLoadRef"></div>'
      ;
   $("main_div").innerHTML = featuresHTML;
   LoadFeatures(1);
   },
   
   
LoadSatelliteFeatures = function()
   {
   var q='&q=SYSD+UG',
   cb = 
      {
      "success": function(o)
         {
         var result = ParseLocally(o.responseText);
         
         if(result.sysd_ug)
            {
            $("BoardIDSpan").innerHTML = result.sysd_ug.serial;
            $("BoardSetSpan").innerHTML = result.sysd_ug.license;
            $("keyDescriptionSpan").innerHTML = GetBoardFeatureKeyDescription(result.sysd_ug.license);
            }
         },
      "failure": function(o){}
      
      };
   GetMyles(cb, q, null);
   },
   
LoadFeatures = function(timeout)
   {
   timeout = (timeout && (!isNaN(timeout)))? timeout: _FEATURES_LOAD_DEF_TIMEOUT;
      
   var XHRSuccess = function(o)
      {
      if(SupportsBoardsInfo())
         {
         RenderBoardsInfoDt();
         }
      var result = ParseLocally(o.responseText);
      $("prodIdSpan").innerHTML = result.sysd_fe.p;
      $("prodSerialSpan").innerHTML = result.sysd_mf.serial;
      var feaDS = new YAHOO.util.LocalDataSource(result.sysd_fe.features);
      feaDS.responseType = YAHOO.util.LocalDataSource.TYPE_JSARRAY;
      
      var columnDef = [];
      columnDef.push({
         key:"name",
         label:'<b>Name</b>', 
         sortable:true,
         selected:false,
         formatter:function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = oData;  
            }
         });
      columnDef.push({
         key:"state",
         label:'<b>Status</b>', 
         sortable:true,
         selected:false,
         formatter:function(elCell, oRecord, oColumn, oData)
            {
            if(oData===0)
               {
               elCell.innerHTML = "DISABLED";
               elCell.style.color =_ADTCOLOR.RED;
               }
            else
               {
               elCell.innerHTML = "ENABLED";
               elCell.style.color =_ADTCOLOR.GREEN;
               }
            }
         });
      if(isNaN(parseInt(result.sysd_fe.t, 10))||(parseInt(result.sysd_fe.t, 10)!==0))
         {
         $("tempFeaIdSpan").innerHTML = "<b>Temporary ID:<b>" + result.sysd_fe.t;
         columnDef.push({
            key:"daysRemaining",
            label:'<b>Expires</b>', 
            sortable:true,
            selected:false,
            formatter:function(elCell, oRecord, oColumn, oData)
               {
               if(oData>=_PERM_KEY_VAL) //
                  {
                  elCell.innerHTML = "NEVER";
                  }
               else
                  {
                  elCell.innerHTML = oData + " days";
                  }
               }
            });
         }
      columnDef.push({
         key:"action",
         label:'<b>Action</b>', 
         sortable:false,
         selected:false,
         formatter:function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = '<img src="/images/inputkey.gif" />';
            }
         });
      var feaDT = new YAHOO.widget.DataTable("featuresDatatable", columnDef, feaDS, {});
      feaDT.subscribe
         (
         "cellClickEvent", 
         function(ev)
            {
            var target = _yuiEvent.getTarget(ev);
            var column = this.getColumn(target);
            var record = this.getRecord(target);
            if(column.key=="action")
               {
               GetInputKey(record);
               }  
            }
         );
      if(SupportsSatelliteFeatures())
         {
         LoadSatelliteFeatures();
         }
      };
   
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX error in FE command");
         }
      };
   
   var query = ''
      + '&q=SYSD+FE'
      + '&q=SYSD+MF'
      ;
   var onLoadFeaturesReady = function()
      {
      GetMyles(XHRCallback, query);
      };
   setTimeout(onLoadFeaturesReady, timeout);

   }, 

/***********************************************************************************************************
 * TODO: Doc
 ***********************************************************************************************************/ 
GetTunerKey = function(record)
   {
   var key = prompt("Please enter the Feature Key.");
   if(key!==null)
      {
      if(IsValidFeatureKey(key))
         {
         SubmitTunerKey(key);
         }
      }
   }, 
   
   
/***********************************************************************************************************
 * TODO: Doc
 ***********************************************************************************************************/ 
GetInputKey = function(record)
   {
   var key = prompt("Please enter the KEY to enable/disable " + record.getData("name"));
   if(key!==null)
      {
      if(IsValidFeatureKey(key))
         {
         SubmitFeatureRequest(record, key);
         }
      }
   }, 
   
/***********************************************************************************************************
 * TODO: Doc
 ***********************************************************************************************************/ 
SubmitTunerKey = function(key)
   {
   var query = 'SYSD SUP ' + key + _NEWLINE;
   
   var XHRSuccess = function(o)
      {
      var response = (o.responseText).toUpperCase();
      var pos = response.search("ERROR-"); 
      if(pos!=-1) //error found
         {
         SetInfoMessage(response.substring(pos), _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.RED);
         }
      else
         {
         SetInfoMessage("Key Entered.", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
         }
      };
      
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("Status change in feature could not be changed");
         }
      }; 
   SetMyles(XHRCallback, query, true, true, LoadFeatures);
   
   }, 

/***********************************************************************************************************
 * TODO: Doc
 ***********************************************************************************************************/
SubmitFeatureRequest = function
   (
   record, 
   key
   )
   {
   //handler has been deprecated.  Only SYSD features are accepted in the current parser.  
//   var query = record.getData("handler") + ' FEA ' + record.getData("name") + " " + key + _NEWLINE ; 
   var query = 'SYSD FEA ' + record.getData("name") + " " + key + _NEWLINE ;
   
   
   var XHRSuccess = function(o)
      {
      var response = (o.responseText).toUpperCase();
      var pos = response.search("ERROR-"); 
      if(pos!=-1) //error found
         {
         SetInfoMessage(response.substring(pos), _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.RED);
         }
      else
         {
         SetInfoMessage("Status of " + record.getData("name") + " succesfully changed", _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.GREEN);
         LoadFeatures(); //updates global variables containing feature status
         }
      };
      
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("Status change in feature could not be changed");
         }
      }; 
   SetMyles(XHRCallback, query, true, true, LoadFeatures);
   }, 
   
   
/***********************************************************************************************************
 * TODO: Doc
 ***********************************************************************************************************/
IsValidFeatureKey = function(key)
   {
   return true;//TODO??
   },
   
/************************************************************
 * Creates a datatable displaying the boards information is displayed on 
 * units that support the boardsinfo API command. 
 *************************************************************/   
RenderBoardsInfoDt = function()
   {
   var q='&q=SYSD+BI';
   var cb = 
      {
      success: function(o)
         {
         var response = ParseLocally(o.responseText);
         var biDs = new YAHOO.util.DataSource(response.sysd_bi); 
         biDs.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
         biDs.responseSchema ={fields      : ['slot', 'id', 'name']};
         var biCols = 
            [
            {
            key:"slot",
            label:'<b>Slot</b>', 
            sortable:true,
            selected:false,
            formatter:function(elCell, oRecord, oColumn, oData)
               {
               elCell.innerHTML = oData;
               }
            },
            {
            key:"id",
            label:'<b>ID</b>', 
            sortable:true,
            selected:false,
            formatter:function(elCell, oRecord, oColumn, oData)
               {
               elCell.innerHTML = oData;
               }
            },
            {
            key:"name",
            label:'<b>Name</b>', 
            sortable:true,
            selected:false,
            formatter:function(elCell, oRecord, oColumn, oData)
               {
               elCell.innerHTML = oData;
               }
            }
            ];
         var biDt = new YAHOO.widget.DataTable("bidDtDiv", biCols, biDs, {sortedBy:{key:"slot",dir:"asc"}});
         }
      };
   GetMyles(cb, q); //submit XH request
   },

/******************************************************************
 * Sends command that wraps up (and/or creates) important files 
 * for diagnostics, and downloads them from the server.
 ******************************************************************/
DownloadDiagnostics = function()
   {
   var markup = ''
    + '<table>'
    +    '<tr><td>Preparing the diagnostics Package. Please wait.</td></tr>'
    +    '<tr><td style="text-align:center"><img src="/images/spinner.gif" /></td></tr>'
    + '</table>'
    ;
   InitModalPanel(markup);
   var cb = 
      {
      success: function(o)
         {
         CloseModalPanel();
         if((o.responseText).search(_REQHANDLER_ERR_MSG_PREFIX)!=-1)
            {
            alert("Error!  The diagnostics package could not be downloaded.  Please verify that your device's disk is not full.  More info can be found in the system logs, which can be accessed on the upper-right corner of your web browser.");
            }
         else
            {
            var fp = _yuiParseJson(o.responseText).filepath;
            if((fp!==undefined) && (fp!== null))
               {
               window.location.target = "_blank";
               window.location.href = "/download?filewdel=" + fp;
               }
            else
               {
               alert("Error!  The diagnostics package could not be downloaded.  Please verify that your device's disk is not full.  More info can be found in the system logs, which can be accessed on the upper-right corner of your web browser.");
               }   
            }
         
         },
      failure: function(o){}
      };
      
   var obj = 
      {
      id: _REQID.PACKFILES, 
      req: Math.random()
      }; //build post arguments object
      
   ConnectToReqHandler(cb, _yuiStringify(obj));
   return false;
   },
   
/******************************************************************
 * TODO: 
 ******************************************************************/
SupportsDiagnosticsDownload = function()
   {
   var result = false; //assume Diagnostics is not supported.
   switch(GetProductId())
      {
      case _PRODUCT.RD60.id:
      case _PRODUCT.MEDIAHUBHD.id:
      case _PRODUCT.MEDIAHUBHD_422.id:
      case _PRODUCT.EDJE5110.id:
      case _PRODUCT.EN40.id:
      case _PRODUCT.EN80.id:
      case _PRODUCT.EN41.id:
      case _PRODUCT.EN81.id:
      case _PRODUCT.EN91.id:
      case _PRODUCT.EN20.id:
         result = true;
         break;

      case _PRODUCT.SIGNEDJE.id: //move product ids to the top, as back-end support is added for other products
      case _PRODUCT.EDJE4111.id:
      case _PRODUCT.SOLOIST411_HW2.id:
      case _PRODUCT.SOLOISTHDPRO.id:
      case _PRODUCT.HDMI2QAM.id:
      case _PRODUCT.YUV2QAM.id:
      case _PRODUCT.DTA.id:
      case _PRODUCT.DPI.id:
      case _PRODUCT.EN10.id:
         result = false;
         break;
      default: 
         result = false;
      }
   return result;
   }
   ;
/*****************************************************************************
 * @file
 * @author  Original:     German Escallon
 * @author  Contributors:
 * @date    Created:      July 2, 2009
 * @date    Last edited:  August 19, 2009
 *
 * This file handles the GUIDE tab
 * Copyright Adtec Digital 2009-2012
 ******************************************************************************/

 
/***************************************************************************************************
 *                                  GUIDE TAB Global Constants.
 *
 * NOTE:  const Keyword is not supported by Internet Explorer. Thus var is used instead.  
 * Treat these variables as #define's (in C/C++ code terms)and (even though its possible)  DO NOT 
 * re-assign any value to them at run time.                                            
****************************************************************************************************/ 
var
   _EDITEITEVTPNLERRORDIVID =       "eitEditPanlErrDivId", 
   _EIT_EDITPNL_DIV =               "eitEditPanelDivId", 
   _EIT_TTIP_DIV =                  "eitTooltipDiv",
   _SRCTYPEHIDDENFLDID =            "srcTypeHiddenFieldId",
   _EITERRORREGEX =                 /EIT SCHEDULER ERROR:/, //must be in sync w/ define EIT_FCGI_ERR_PREFIX (see /app/eit_scheduler/src/eit_scheduler_main.h).
   _EITOVERLAPERRORREGEX =          /OVERRIDE overlaps an existing entry/, //must be in sync w/ define EIT_OVERRIDE_OVERLAP_STR (see /app/eit_scheduler/src/eit_scheduler_main.h). 
   _CHGUIDE_DT_CSSCLASS =           "dta-selected-row", //see {project}/dta/css/*.css.
   _GUIDE_TOOLTIP_WIDTH =           "100 px",
   _EIT_GUIDE_PNL_WIDTH =           "500px",
   
   
   
   //NOTE.  Must be in sync w/ 
   _EIT_SRCTYPE =  //enum used to identify source type for EIT events
      {
      "A76":   0, //indicates EIT event comes from an A76XML file
      "ORDB":  1  //indicates EIT event comes from an entry on the override database
      },
 
   
   
   
   _GUIDEDATATABLEHEIGHT = "50em"
   ;
 
/****************************************************************************************************
                                  GUIDE TAB Global Variables
****************************************************************************************************/
var
   _channGuideDatatable = null, //datatable instance of channel guide 
   _currEITProgramObj = null,
   _delEitEvtColId = null,      //id of delete override column (if any)
   _editEitPanel = null, //editEitPanel object
   _guideListenersSet
   ;
 
var
 
/******************************************************************************
* Entry point for GUIDE tab.  Sets and renders HTML markup required for this tab, 
* initializes datatables to be displayed, as well as render the panel object 
* required for eit overrides.  
******************************************************************************/
RenderGuide = function()
   {
   _guideListenersSet = false;
   var guideHTML = ''
      +  '<b>Guide</b><br />'
      +  '<div id="' + _EIT_EDITPNL_DIV + '"></div>' //placeholder for panel
      +  '<div id="' + _EIT_TTIP_DIV + '"></div>' //placeholder for tooltip
      +  '<table><tr>'
      +  '  <td valign="top"><div id="channelLineupTable" style="cursor: pointer;"></div></td>'
      +  '  <td valign="top" id="channelGuideTableTd" ><div id="channelGuideTable"></div></td>'
      +  '</tr></table>'
      ;
   $("main_div").innerHTML = guideHTML;    
   $(_EIT_TTIP_DIV).className = "yui-tt";

   _yuiEvent.onAvailable("channelLineupTable", LoadGuide, this);   //triggers LoagGuideTab function
   },

LoadGuide = function()
   {
   InitChannelLineupTable();   //initializes datatable
   InitChannelGuideTable(); 
   RenderEitGuidePanelAndTtip();  //renders panel used to edit/update EIT events, and tooltip used when hovering over an event
   },   
   
   
/***************************************************************
 *  Initializes, configures and renders table containing the list of available
 *  channels on the box. 
 ***************************************************************/
InitChannelLineupTable = function()
   {
   var channLineupDS = new YAHOO.util.DataSource(_EITSCH_LOC);
   channLineupDS.responseType = YAHOO.util.DataSource.TYPE_JSON;//define type of response
   channLineupDS.connMethodPost = true; //set connection method as POST
   channLineupDS.responseSchema = 
      { //defines how to parse response
      resultsList: "Channels",
      fields:
         [
         "ch_key",
         "ch_num",
         "ch_name"
         ]
      };
      
      
   var colDef = 
      [
         {
         key: "ch_num",
         label: "<b>#</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = oData;
            }
         },
         
         {
         key: "ch_name",
         label: "<b>Program Name</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = oData;
            }
         }//,
         
//         {
//         key: "showGuide",
//         label: "<b>Show Guide</b>",
//         resizeable: true,
//         sortable: true,
//         formatter: function(elCell, oRecord, oColumn, oData)
//            {
//            elCell.innerHTML = "<button>ShowGuide</button>";
//            }
//         }
         
      ];
      
   
   //async event triggered when user clicks on a cell inside the datatable   
   var OnCellClick = function(ev)
      {
      var target = YAHOO.util.Event.getTarget(ev);
      var programRecObj = this.getRecord(target);
      ShowGuideForProgram(programRecObj); 
      };
   
   //build initial request object
   var reqObj = 
      {
      id:     _EIT_REQID.GETAVAILABLEPROGRAMS,
      req: Math.random()         
      };
   //transform request object into json string
   var reqStr = _yuiStringify(reqObj); //transform object to string
         
   var channLineupConf = 
         {
         initialRequest: reqStr //postadata string in JSON format  
         };   
   var channLineupDatatable = new YAHOO.widget.DataTable("channelLineupTable", colDef, channLineupDS, channLineupConf);
   channLineupDatatable.CLASS_SELECTED = _CHGUIDE_DT_CSSCLASS;
   //subscribe to asynchronous event of user clicking on a cell in the datatable   
   channLineupDatatable.subscribe('cellClickEvent', OnCellClick); 
   channLineupDatatable.subscribe("rowClickEvent",channLineupDatatable.onEventSelectRow);     
   
   }, 
   
   
/***************************************************************
 *  Initializes, configures and renders table containing the list of available
 *  programs for a given channel.  Hidden initially upon page load.  
 ***************************************************************/
InitChannelGuideTable = function()
   {
      
   var channGuideDS = new YAHOO.util.DataSource(_EITSCH_LOC);
   channGuideDS.responseType = YAHOO.util.DataSource.TYPE_JSON;//define type of response
   channGuideDS.connMethodPost = true; //set connection method as POST
   channGuideDS.responseSchema = 
      { //defines how to parse response
      resultsList: "Events",
      fields: //NOTE: Not all fields (metadata) will be displayed on the table.
         [
         "ch_key",            "startTime",         "endTime",              "duration",          
         "description",       "star_rating",       "mpaa_rating",          "slvContent_rating", 
         "showName",          "epi_title",         "cast",                 "release_year",      
         "show_type",         "cc",                "stereo",            "sourceType"
         ] //TODO: Define and replace magic values
      };

   var colDef = 
      [
         {
         key: "startTime",
         label: "<b>Start</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            var d = new Date();
            d.setTime(oData*1000);
            var dow = _DAYSOFWEEK[d.getDay()];
            var hours = (d.getHours()>=10 ? d.getHours(): '0' + d.getHours() );
            var minutes = (d.getMinutes()>=10 ? d.getMinutes(): '0' + d.getMinutes() );
            
            elCell.innerHTML =  dow + " " + hours + ":" + minutes;
            }
         },
         {
         key: "endTime",
         label: "<b>End</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            var d = new Date();
            d.setTime(oData*1000);
            var dow = _DAYSOFWEEK[d.getDay()];
            var hours = (d.getHours()>=10 ? d.getHours(): '0' + d.getHours() );
            var minutes = (d.getMinutes()>=10 ? d.getMinutes(): '0' + d.getMinutes() );
            
            elCell.innerHTML =  dow + " " + hours + ":" + minutes;
            }
         },
         {
         key: "showName",
         label: "<b>Name</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = oData;
            }
         },
         {
         key: "epi_title",
         label: "<b>Title</b>",
         resizeable: true,
         sortable: true,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = oData;
            }
         },

         {
         key: "edit",
         label: "",
         resizeable: true,
         sortable: false,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            elCell.innerHTML = '<button>Edit</button>';
            elCell.style.cursor = "pointer";
            }
         },
         
         {
         key: "delete",
         label: "",
         resizeable: true,
         sortable: false,
         formatter: function(elCell, oRecord, oColumn, oData)
            {
            switch(oRecord.getData("sourceType"))
               {
               case _EIT_SRCTYPE.ORDB:
                  elCell.innerHTML = '<img src="/images/x.gif" />';
                  elCell.style.cursor = "pointer";
                  break;
               case _EIT_SRCTYPE.A76:
                  elCell.innerHTML = '<img src="/images/x_disabled.gif" />';
                  elCell.style.cursor = "";
                  break;
               default:
                  break;
               }
            }
         }
         
      ];

//Async event that displays the EIT information in a tooltip.  Triggered when user hovers over a record ont the datatable   
   var OnMouseOver = function (ev)
      {
      var recObj = this.getRecord(_yuiEvent.getTarget(ev));
      var row = this.getTrEl(recObj);
      //sets tooltip
       
      var tt = new YAHOO.widget.Tooltip
      (
         "" + Math.random() + "" , //random tooltip id
         { 
         text: GetEitStrFromDTRec(recObj),
         context: row.id,  
         container: _EIT_TTIP_DIV,
         width:   _GUIDE_TOOLTIP_WIDTH
         }
      ); 
      
      };
   
//Async event triggered when user clicks on datatable   
   var OnCellClick = function(ev)
      {
      var target = YAHOO.util.Event.getTarget(ev);
      var column = this.getColumn(target);
      var eitEventObj = this.getRecord(target);
      switch(column.key)
         {
         case "edit":
            DisplayEditEITPanel(eitEventObj);
            break;
         
         case "delete":
            switch(eitEventObj.getData("sourceType")) 
               {
               case _EIT_SRCTYPE.ORDB: //this is an override entry.
                  if(confirm("Delete Override Entry?\n(This action can't be undone)"))
                     {
                     DeleteOverrideEvtFromDTRec(eitEventObj);      
                     }
                  break;
        
               case _EIT_SRCTYPE.A76:
                  break;  
               default:
                  break;
               }
            break;
         
         default:
            break;
               
         }         
      };
  
   // Define custom row formatter function to distinguish override entries
   var ConditionalRowFormatter = function(elTr, oRecord) 
      {
      switch(oRecord.getData("sourceType")) 
         {
         case _EIT_SRCTYPE.ORDB: //this is an override entry.
            elTr.style.backgroundColor = GetProductColor(); //highlights override events to distinguish them from A76-based events
            break;
        
         case _EIT_SRCTYPE.A76:
            break;  
         default:
            break;
         }
      return true;
      }; 
   
   var tbConf = 
      {
      height:        _GUIDEDATATABLEHEIGHT,
      MSG_EMPTY:     "Select a Channel from the list to display its guide information.",
      formatRow:     ConditionalRowFormatter,
      initialLoad:   false //prevents table from doing AJAX request when first created.
      };      
   
   //render datatable
   _channGuideDatatable = new YAHOO.widget.ScrollingDataTable("channelGuideTable", colDef, channGuideDS, tbConf);
   
   //subscribe to asynch event when user clicks on a cell.
   _channGuideDatatable.subscribe('cellClickEvent', OnCellClick);
   _channGuideDatatable.subscribe("rowMouseoverEvent", OnMouseOver);
   }, 
   
   
/*************************************************
 * Prepares postdata used to request Guide information
 * for a given program (channel number), and submits request
 * to retrieve it.
 * Triggered when user selects a channel from the channel lineup table. 
 *************************************************/   
ShowGuideForProgram = function(programRecObj)
   {
   
   _currEITProgramObj = programRecObj;
   
   var reqObj = 
      {
      id:         _EIT_REQID.SHOWGUIDEFORPROGRAM,
      req:        Math.random(),
      ch_key:     programRecObj.getData("ch_key")
      } ;
   var reqStr = _yuiStringify(reqObj); //transform object to string
   ReloadChGuideDatatable(reqStr);
   
   }, 
   
   
/***********************************************************
 *  Loads and displays guide information for a given program. 
 ***********************************************************/   
ReloadChGuideDatatable = function(reqStr)
   {
   SetCursorWait();
   
   var datasource = _channGuideDatatable.getDataSource();
   
   //delete all existing rows
   _channGuideDatatable.initializeTable(); //deletes old records from recordset (if any)
   _channGuideDatatable.disable(); //greys out datatable
   
   //define success handler for datasource request callback
   var XHRSuccess = function() 
      {
      this.onDataReturnAppendRows.apply(this, arguments); //appends newly retrieved records
      this.render(); //renders datatable with updated data
      ResetCursor();
      //re-enables
      _channGuideDatatable.undisable();
      };
      
   //define callback object for datasource
   var dsCallback = 
      {
      success : XHRSuccess,
      failure : function()
         {
         LogMyles("AJAX Error: Request: " + reqStr + " failed");
         },
      scope : _channGuideDatatable
      };
   datasource.sendRequest(reqStr, dsCallback); //submits new request
   }, 
 

/*****************************************
 * Renders Panel used to edit an EIT event.
*****************************************/
RenderEitGuidePanelAndTtip = function()
   {
   //sets panel configurations
   var pnlConf = 
      {
      width: _EIT_GUIDE_PNL_WIDTH, 
      autofillheight: "body", 
      fixedcenter: true, 
      constraintoviewport: true, 
      underlay:"matte",
      modal: true, 
      close:true,     
      visible:false,  //hidden by default
      draggable:true 
      };
   
   //creates panel object
   _editEitPanel = new YAHOO.widget.Panel(_EIT_EDITPNL_DIV, pnlConf);
   
   //sets panel html
   var pnlHtml = ''
      +  '<form id="editEitPanelFrm">'
      +  '<table>'
      +  '   <tr><td colspan="2"><div id="' + _EDITEITEVTPNLERRORDIVID + '" style="color:' +_ADTCOLOR.RED + '"></div></td></tr>'

      +  '<tr>'
      +  '  <td><b>Start Time:</b><input id="startTimeTextfield"></input></td>'
      +  '  <td><b>End Time:</b><input id="endTimeTextfield"></input></td>'
      +  '</tr>'
      
      +  '<tr>'
      +  '  <td><b>Show Name:</b><input id="showNameTextfield" maxlength="256"></input></td>'
      +  '  <td><b>Episode Title:</b><input id="episodeTitleTextfield" maxlength="256"></input></td>'
      +  '</tr>'
      
      +  '<tr>'
      +  '  <td><b>Duration:</b><input id="durationTextfield"></input></td>'
      +  '  <td><b>Release Year:</b><select id="releaseYearSelect">' + GetSelectOptions("guide_releaseYear") + '</select></td>' 
      +  '</tr>'

      +  '<tr>'
      +  '  <td><b>Description:</b><br /><textarea id="descriptionTextarea"></textarea></td>'
      +  '  <td><b>Cast:</b><br /><textarea id="castTextarea"></textarea></td>'
      +  '</tr>'
      
      
      +  '<tr>'
      +  '  <td><b>Mpaa Rating:</b><select id="mpaaRatingSelect">' + GetSelectOptions("guide_mpaaRating") + '</select></td>'
      +  '  <td><b>Star Rating:</b><select id="starRatingSelect">' + GetSelectOptions("guide_starRating") + '</select></td>'
      +  '</tr>'
      
      
      +  '<tr>'
      +  '  <td><b>SLV Content:</b><select id="slvContentSelect">' + GetSelectOptions("guide_slvContent") + '</select></td>'
      +  '  <td><b>Show Type:</b><input id="showTypeTextfield" maxlength="256"></input></td>' 
      +  '</tr>'
                  
      +  '<tr>'
      +  '  <td><b>CC:</b><select id="ccSelect">' + GetSelectOptions("guide_cc") + '</select></td>'
      +  '  <td><b>Stereo:</b><select id="stereoSelect">' + GetSelectOptions("guide_stereo") + '</select></td>'
      +  '</tr>'
      
      +  '</table>'
      +  '<br /><br />'
      +  '<input type="hidden" id="' + _SRCTYPEHIDDENFLDID + '" />'
      +  '<button id="editEventImg">Edit Event</button>&nbsp;&nbsp;' //TODO: Replace button for image
      +  '<button id="cancelEditEventImg">Close</button><br />' //TODO: Replace button for image
      +  '</form>'
      ;
      
    
   _editEitPanel.setHeader("Edit EIT Event");
   _editEitPanel.setBody(pnlHtml);
   _editEitPanel.render();
   
   var SetEditEITFormListeners = function()
      {//Sets the event listeners for items in the EIT Edit Form
      
      //sets onclick for submit button
      _yuiEvent.addListener( // submit
         "editEventImg", //id to attach event listener to 
         "click",  //type of event
         ValidateEditEITForm, //method to be invoked
         $("editEitPanelFrm"), //object passed as argument
         true//set object as scope of handler
         );
      
      //sets onclick event for cancel button
      _yuiEvent.addListener( //current scheduler chk box
         "cancelEditEventImg", //id to attach event listener to 
         "click",  //type of event
         ResetAndCloseEditEITPanelForm, //method to be invoked
         null, //object passed as argument
         false//set object as scope of handler
         );
      
      //sets onchange event for start time
      _yuiEvent.addListener( //sch action selector
         ["startTimeTextfield", "endTimeTextfield"], //id(s) to attach event listener to 
         "change",  //type of event
         CalculateEITEventDuration, //method to be invoked
         null, //object passed as argument
         false //set object as scope of handler
         );
      
      //sets onchange event for start time
      _yuiEvent.addListener( //sch action selector
         "durationTextfield", //id(s) to attach event listener to 
         "change",  //type of event
         CalculateEITEventEndTime, //method to be invoked
         null, //object passed as argument
         false //set object as scope of handler
         );
      _guideListenersSet = true;
      };
   //listens to panel render event to trigger sch form actions.   
   if(!_guideListenersSet){_yuiEvent.onAvailable("editEitPanelFrm", SetEditEITFormListeners, this);}
   
   
   }, 
 
 
 
/******************************************************************************
 * Ensures that data submitted by user when editing an event is valid.
******************************************************************************/
ValidateEditEITForm = function()
   {
   var errStr = null;
   //validate Start Time
   if(isNaN(Date.parse(Trim($("startTimeTextfield").value))))
      {
      errStr = "Invalid Start Time";
      }
   
   //validate End time
   if(isNaN(Date.parse(Trim($("endTimeTextfield").value))))
      {
      errStr = "Invalid End Time";
      }
   if(errStr===null)
      { //data is correct..  Proceed to submit
      SubmitEditedEITEvent();
      }
   else
      {//Error found.  display error message and abort submission of eit event
      $(_EDITEITEVTPNLERRORDIVID).innerHTML = errStr;
      }
   }, 
   
   
/*******************************************************************************
 * Resets and closes panel containing form for event overrides.  Triggered when
 * user cancels action, or when it closes the panel.
 *******************************************************************************/
ResetAndCloseEditEITPanelForm = function()
   {
   _editEitPanel.hide();
   }, 
   
 
 
/*********************************************************************
 *  Displays pre-rendered panel.  Triggered by clicking the "EDIT"
 *  column on the channel guide datatable.  Pre-populates fields
 *  inside the edit form with data representing the event being clicked at.
 *********************************************************************/
DisplayEditEITPanel = function(eitEventObj)
   {
   //Pre-populate form w/ EIT Event information
   $(_EDITEITEVTPNLERRORDIVID).innerHTML = ''; //resets contents in case of previous errors  
 
   if(eitEventObj.getData("duration")<0) //invalid duration
      {//calculate duration by substracting endtime from startTime
      
      eitEventObj.setData("duration", 
         (eitEventObj.getData("endTime") - eitEventObj.getData("startTime"))
         );
      }
   if(eitEventObj.getData("sourceType") != _EIT_SRCTYPE.ORDB)
      {//this is the default behavior, thus all fields are enabled..  Set in here to reset its default values, in case these fields have been disabled on previous interactions
      $("startTimeTextfield").disabled = false; //TODO: replace magic value
      $("endTimeTextfield").disabled = false; //TODO: replace magic value
      $("durationTextfield").disabled  = false; //TODO: replace magic value
      }
   else
      {//This is an edit of an existing override record, not a new one. Thus, start time, endtime and duration fields are disabled to prevent conflicts when merging override events w/ A76 injected events
      $("startTimeTextfield").disabled = true; //TODO: replace magic value
      $("endTimeTextfield").disabled = true; //TODO: replace magic value
      $("durationTextfield").disabled  = true; //TODO: replace magic value
      }
   //populate form data   
   $("durationTextfield").value     = MilisecondsToHHMMSS(eitEventObj.getData("duration") * _MILISECONDSPERSECOND); //duration is in seconds, thus it must be multiplied by the num of miliseconds in a sec (1000).
   $("showNameTextfield").value     = eitEventObj.getData("showName");
   $("episodeTitleTextfield").value = eitEventObj.getData("epi_title"); 
   $("releaseYearSelect").value     = eitEventObj.getData("release_year"); 
   $("descriptionTextarea").value   = eitEventObj.getData("description");
   $("castTextarea").value          = eitEventObj.getData("cast");
   $("mpaaRatingSelect").value      = eitEventObj.getData("mpaa_rating");
   $("starRatingSelect").value      = eitEventObj.getData("star_rating");
   $("slvContentSelect").value      = eitEventObj.getData("slvContent_rating");
   $("showTypeTextfield").value     = eitEventObj.getData("show_type");
   $("ccSelect").value              = eitEventObj.getData("cc");
   $("stereoSelect").value          = eitEventObj.getData("stereo");
   $(_SRCTYPEHIDDENFLDID).value     = eitEventObj.getData("sourceType");
   var d = new Date(eitEventObj.getData("startTime")*_MILISECONDSPERSECOND);
   $("startTimeTextfield").value = d;
   
   d     = new Date(eitEventObj.getData("endTime")*_MILISECONDSPERSECOND); 
   $("endTimeTextfield").value = d;
         
   
   _editEitPanel.show(); //display panel
        
   }, 
 
 /*********************************************************************
 *  Triggered by modifying the duration field when editing a new event, 
 *  this function keeps startTime, endTime and duration fields in synch 
 *  by re-calculating the end time of the event.  
 *********************************************************************/
CalculateEITEventEndTime = function()
   {
   $(_EDITEITEVTPNLERRORDIVID).innerHTML = ''; //resets panell error division
   var startTimeInMiliseconds  = Date.parse(Trim($("startTimeTextfield").value));
   var durationInMiliseconds = HHMMSSToMiliseconds(Trim($("durationTextfield").value));
   if(durationInMiliseconds==_INVALID_DURATION_IN_MSECS)
      {//error found 
      $(_EDITEITEVTPNLERRORDIVID).innerHTML = "Duration must be in HH:MM:SS format. "; 
      }
   else
      {
      var endDate = new Date(startTimeInMiliseconds + durationInMiliseconds);
      $("endTimeTextfield").value = endDate;      
      }
   
   }, 
 
 /*********************************************************************
 *  Triggered by modifying the start and/or endTime when editing a new event, 
 *  this function keeps startTime, endTime and duration fields in synch 
 *  by re-calculating the duration of the event.  
 *********************************************************************/
CalculateEITEventDuration = function()
   {
   var startTimeInMiliseconds  = Date.parse(Trim($("startTimeTextfield").value));
   var endTimeInMiliseconds  = Date.parse(Trim($("endTimeTextfield").value));
   var  durationInMiliseconds= endTimeInMiliseconds - startTimeInMiliseconds;
   $("durationTextfield").value     = MilisecondsToHHMMSS(durationInMiliseconds);
     
   }, 
 
 
/*************************************************
 * Submits AJAX request to update eit event, and 
 * refreshes displayed table upon success. 
*************************************************/
SubmitEditedEITEvent = function()
   {
   var XHRSuccess = function(o)
      {
      if(!_EITOVERLAPERRORREGEX.test(o.responseText))
         {
         ShowGuideForProgram(_currEITProgramObj);//reloads table for current event
         _editEitPanel.hide();
         }
      else
         { //overlap error found when submitting eit entry
         $(_EDITEITEVTPNLERRORDIVID).innerHTML = o.responseText;
         }
      };
   
   
   var XHRCallback = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX ERROR: Eit Override not submitted.");
         }
      };
   
   //calculate startTime in seconds
   var i_startTime = Date.parse(Trim($("startTimeTextfield").value)) / _MILISECONDSPERSECOND ; 
   
   //calculate endTime in seconds
   var i_endTime   = Date.parse(Trim($("endTimeTextfield").value)) / _MILISECONDSPERSECOND; 
   
   //create postdata event used to submit to the server
   var eitOverrideObj = 
      {
      id:                  _EIT_REQID.SUBMITOVERRIDEENTRY,
      req:                 Math.random(), //prevent browser from caching request
      ch_key:              _currEITProgramObj.getData("ch_key"),
      showName:            Trim($("showNameTextfield").value),  
      epi_title:           Trim($("episodeTitleTextfield").value), 
      release_year:        parseInt($("releaseYearSelect").value, _DEFAULT_NUM_BASE),     
      description:         Trim($("descriptionTextarea").value),            
      cast:                Trim($("castTextarea").value),
      mpaa_rating:         parseInt($("mpaaRatingSelect").value, _DEFAULT_NUM_BASE),
      star_rating:         parseInt($("starRatingSelect").value, _DEFAULT_NUM_BASE),
      slvContent_rating:   parseInt($("slvContentSelect").value, _DEFAULT_NUM_BASE),
      show_type:           Trim($("showTypeTextfield").value),
      cc:                  parseInt($("ccSelect").value, _DEFAULT_NUM_BASE),         
      stereo:              parseInt($("stereoSelect").value, _DEFAULT_NUM_BASE),
      startTime:           i_startTime,
      endTime:             i_endTime,
      duration:            (i_endTime - i_startTime), //duration is calculated by substracting endTime from startTime and prevent inconsistencies
      sourceType:          $(_SRCTYPEHIDDENFLDID).value   
      };
   var eitOverridePostdataStr = _yuiStringify(eitOverrideObj); //transform object to string

   //Submit XHR
   ConnectToEitScheduler(XHRCallback, eitOverridePostdataStr); 
   
     
   }, 
 
 
/******************************************************************
 * Obtains eit data from record obj, and returns it as a single 
 * string to be used as the contents of the tooltip.
 * Activated when hovering over a datatable element
 ******************************************************************/
GetEitStrFromDTRec = function(recObj) 
   {
      
   var stTime = new Date(recObj.getData("startTime") * _MILISECONDSPERSECOND);
   var endTime =  new Date(recObj.getData("endTime") * _MILISECONDSPERSECOND);

   var stTimeStr = DateObjToDateTimeStr(stTime);
   var endTimeStr = DateObjToDateTimeStr(endTime);
   
   
   var releaseYr = (recObj.getData("release_year")<_MIN_RELEASE_YEAR || recObj.getData("release_year")>_MAX_RELEASE_YEAR)? _NA: recObj.getData("release_year"); 
   var result = ''
      +  '<table>'
      +  '<tr>'
      +  '  <td><b>Start Time:</b></td><td>' + stTimeStr + '</td>'
      +  '  <td><b>End Time:</b></td><td>' + endTimeStr + '</td>'
      +  '</tr>'
      
      +  '<tr>'
      +  '  <td><b>Show Name:</b></td><td>' + recObj.getData("showName") + '</td>'
      +  '  <td><b>Episode Title:</b></td><td>' + recObj.getData("epi_title") + '</td>'
      +  '</tr>'
      
      +  '<tr>'
      +  '  <td><b>Duration:</b></td><td>' + recObj.getData("duration") + '</td>'
      +  '  <td><b>Release Year:</b></td><td>' + releaseYr + '</td>' 
      +  '</tr>'
      
      
      +  '<tr>'
      +  '  <td><b>Mpaa Rating:</b></td><td>' + _MPAA_RATING_STR[recObj.getData("mpaa_rating")] + '</td>'
      +  '  <td><b>Star Rating:</b></td><td>' + _STAR_RATING_STR[recObj.getData("star_rating")] + '</td>'
      +  '</tr>'
      
      +  '<tr>'
      +  '  <td><b>SLV Content:</b></td><td>' + _SLV_CONTENT_STR[recObj.getData("slvContent_rating")] + '</td>'
      +  '  <td><b>Show Type:</b></td><td>' + recObj.getData("show_type") + '</td>' 
      +  '</tr>'
                  
      +  '<tr>'
      +  '  <td><b>CC:</b></td><td>' + _CLOSED_CAPTION_STR[recObj.getData("cc")] + '</td>'
      +  '  <td><b>Stereo:</b></td><td>' + _STEREO_STR[recObj.getData("stereo")] + '</td>'
      +  '</tr>'
 
      +  '<tr>'
      +  '  <td><b>Description:</b><br />' + recObj.getData("description") + '<td></td></td>'
      +  '  <td><b>Cast:</b><br />' + recObj.getData("cast") + '<td></td></td>'
      +  '</tr>'
           
      +  '</table>'
      ;   
   
   
   
   return result;
   }, 
 
 
/**************************************************************************************************
 * Deletes Override event from the server.  Uses metadata contained in the record object representing
 * the EIT event being deleted.
 *************************************************************************************************/
DeleteOverrideEvtFromDTRec = function(eitOverrideObj)
   {
   var XHRSuccess = function(o)
      {
      if(_EITERRORREGEX.test(o.responseText))
         {//EIT Error found
         SetInfoMessage(o.responseText, _DEFAULT_INFO_MSG_TIMEOUT,_ADTCOLOR.RED);
         LogMyles(o.responseText);
         }
      else
         {//success.
         ShowGuideForProgram(_currEITProgramObj);//reloads table for current channel guide
         }
      };
   
   var XHRCllbck = 
      {
      success: XHRSuccess,
      failure: function(o)
         {
         LogMyles("AJAX Error: Override event not deleted");   
         }
      };
   var reqObj = 
      {
      id:                  _EIT_REQID.DELETEOVERRIDEENTRY,
      req:                 Math.random(), //prevent browser from caching request
      startTime:           eitOverrideObj.getData("startTime"),
      endTime:             eitOverrideObj.getData("endTime"),
      ch_key:              eitOverrideObj.getData("ch_key") 
      };
   
   var reqStr = _yuiStringify(reqObj); //transform object to string
   //Submit XHR
   ConnectToEitScheduler( XHRCllbck, reqStr);
   
   }
   ;
 
/*****************************************************************************
* @file
* @author Original: N/A
* @author Contributors: Michael Turner
* @date Created: 2010/06/29
* @date Last Edit: $Date$ by $Author$
* Description: Display functions for DTA.
******************************************************************************/
var
/*************************************************************
* Generate the status panel for DTA.
 * @returns {String}
*************************************************************/
GetStatusPanelHTMLDTA = function()
   {
   var statusHTML = ''
      +  GetStatusPanelStdHeader()
      +  '<table>'
      +   '<tr><td><div style="color:#993333;" id="boxStatus"></div></td></tr>'
      +     '<tr>'
      +     '<td><a href="/asimux/system.py"><img src="/images/login2.gif" alt="Return to Multiplexer Controller App"></img></td>' //TODO: Need an icon here.
      +     '</tr>'
      +  '</table>'
      +'</table><br />'
      + '<br/><center><img src="/images/adteclogogray.png"/></center>'
      ;
   return statusHTML;
   }, 

/*************************************************************
 * Follow up status panel generation with visual updates
 * specific to DTA.
 ************************************************************/
GetVisualUpdatesDTA = function()
   {
   }, 
   
/*******************************************************************
 * Update the status panel for DTA
 ******************************************************************/
UpdateStatus_DTA = function()
   {
//   $('status_dest').innerHTML = '<img src="/images/red.gif"></img>';
//   $('status_inputled').innerHTML = '<img src="/images/green.gif"></img>';
//   $('status_inputled2').innerHTML = '<img src="/images/red.gif"></img>';
//   $('status_inputled3').innerHTML = '<img src="/images/red.gif"></img>';
//   $('status_inputled4').innerHTML = '<img src="/images/nolight.gif"></img>';
//   $('status_inputled5').innerHTML = '<img src="/images/yellow.gif"></img>';
   }, 
  
/*******************************************************************
 * Generate the navigation bar for DTA
 * @return  {String}
 ******************************************************************/
LoadNav_DTA = function()
   {
   var menuHTML = ''
      +  '<div id="' + _MAIN_MENU_ID + '" class="yuimenubar yuimenubarnav">' 
      
//         +  '        <div class="navigationitem" id="navinputs">'
//         +  '          <a class="navigationlink" >Inputs</a>' 
//         +  '        </div>'   
//         
//         
//         +  '        <div class="navigationitem" id="destinations">'
//         +  '          <a class="navigationlink" >Destinations</a>' 
//         +  '        </div>'   
      
//         +  '        <div class="navigationitem" id="navguide">'
//         +  '          <a class="navigationlink" >Guide</a>' 
//         +  '        </div>'   
//         
      
//         +  '        <div class="navigationitem" id="system">'
//         +  '          <a class="navigationlink" >System</a>' 
//         +  '        </div>'   

      +  '        <div class="navigationitem" id="upgrade">'
      +  '          <a class="navigationlink"  >Upgrade</a>' 
      +  '        </div>'
//    
//         +  '        <div class="navigationitem" id="help">'
//         +  '          <a class="navigationlink"  >Help</a>' 
//         +  '        </div>'     
      +  '</div>'     
         ;
   return menuHTML;
   }
   ;/*****************************************************************************
* @file
* @author Original: Michael Turner
* @author Contributors: N/A
* @date Created: 2011/03/07
* @date Last Edit: $Date$ by $Author$
* Description: Display functions for DTA.
******************************************************************************/

var _dtvChanged = [];
var
/*************************************************************
* Generate the status panel for DTA.
 * @returns {String}
*************************************************************/
RenderDtvConfig = function()
   {
   LoadDtvConfig();
   var displayHTML = ''
      + '<br/><br/>'
      + '<form id="dtvConfigForm">'
      + '<table style="width: 100%"><tr><td style="vertical-align: top">'
      // action buttons

      // submits form
      + '<a onclick="return ValidateDtvConfigForm();" > '
      + '  <img src="/images/apply.gif" />' 
      + '</a>'
      + '&nbsp;&nbsp;&nbsp;'

      // reloads tab
      + '<a onclick="return LoadDtvConfig();"> ' 
      + '  <img src="/images/cancel.gif" />'
      + '</a>'
      + '</td>'
      
      // dtvguide logo
      + '<td><img src="../images/dtv_guidelogo.png" alt="DTVGuide"/></td>'
      + '</tr></table>'
      + '<br/>'
      
      // actual page
      + '<table style="width: 100%">'
      + '<tr>'
      + '<td>Server Address:<img onclick="ShowHelp(&quot;hlp_dvsrvip&quot;, this);" src="/images/hints.gif"/></td>'
      + '<td><input id="dtvGuideSrvIpTextfield" onchange="_dtvChanged[&quot;address&quot;]=true;"/></input></td>'
      ;
   if(IsJaguar2())
      {
      displayHTML += ''
         +  '<td>Port: <img onclick="ShowHelp(&quot;hlp_dvport&quot;, this);" src="/images/hints.gif"/></td>'
         +  '<td><input id="portTextfield" onchange="_dtvChanged[&quot;address&quot;]=true;"/></td>'
         ;
      }
   else
      {
      displayHTML += ''
         + '<td>FTP Password: <img onclick="ShowHelp(&quot;hlp_ftppass&quot;, this);" src="/images/hints.gif"/></td>'
         + '<td><input type="password" id="dtvFtpPwdTextfield" onchange="_dtvChanged[&quot;ftppass&quot;]=true;"/></td>'
         ;
      }
   
      
   displayHTML += ''
      + '</tr><tr>'
      + '<td>Device Serial No.: <img id="deviceSerialHint" onclick="ShowHelp(&quot;hlp_dvs&quot;, this);" src="/images/hints.gif"/></td>'
      + '<td><input type="text" id="dtvUserNameTextfield" onchange="_dtvChanged[&quot;serial&quot;]=true;"></input></td>'
      + '<td>Download Polling Interval: <img id="downPollHint" onclick="ShowHelp(&quot;hlp_dpi&quot;, this);" src="/images/hints.gif"/></td>'
      + '<td><input id="dtvPollIntervalTextfield" onchange="_dtvChanged[&quot;poll&quot;]=true;"/></td>'
      + '</tr>'
      + '<tr>'
      + '</table>'
      
      // force download
      + '<button type="button" name="forceEPG" onclick="return ForceEPGDownload();">Force EPG Download</button>'
      + '<img id="forceEPGHint" onclick="ShowHelp(&quot;hlp_fepg&quot;, this);" src="/images/hints.gif"/><br /><br />'
      // submits form
      + '<a onclick="return ValidateDtvConfigForm();" > '
      + '  <img src="/images/apply.gif" />' 
      + '</a>'
      + '&nbsp;&nbsp;&nbsp;'

      // reloads tab
      + '<a onclick="return LoadDtvConfig();"> ' 
      + '  <img src="/images/cancel.gif" />'
      + '</a>'
      + '</form>'
      + '<br/><br/>'
      
      ;
   
   $("main_div").innerHTML = displayHTML;
   },
   
/*************************************************************
 * Reset tracking flags
 *************************************************************/
ResetDtvTrackerFlags = function()
   {
   _dtvChanged["address"] = false;
   _dtvChanged["serial"] = false;
   _dtvChanged["poll"] = false;
   _dtvChanged["ftppass"] = false;
   },
   
/*************************************************************
 * Load DTVguide page values
 *************************************************************/
LoadDtvConfig = function()
   {
   ResetDtvTrackerFlags();
   var query = ''
      + '&q=EIT_SCH+GUL+-P'
      + '&q=EIT_SCH+GUL+-C'
      + '&q=SYSD+CPW'
      ;
   
   var XHRCallback = 
      {
      success: function (o)
         {

         if(ParseResponse(o))
            {
            $("dtvPollIntervalTextfield").value = setting["eit_sch_gul"]["poll"];
            if (IsJaguar2())
               {
               $("dtvGuideSrvIpTextfield").value = setting["eit_sch_gul"]["address"];
               $("dtvUserNameTextfield").value = setting["eit_sch_gul"]["serial"];
               $("portTextfield").value =  setting["eit_sch_gul"]["port"]; 
               }
            else
               {
               $("dtvGuideSrvIpTextfield").value =  setting["eit_sch_gul"]["address"];
               $("dtvUserNameTextfield").value =  setting.sysd_cpw.user;
               $("dtvFtpPwdTextfield").value = setting.sysd_cpw.pwd;
               }
            }
         else
            {
            LogMyles("Parse error in DTV Config settings");
            }
         },
      failure: function (o)
         {
         LogMyles("AJAX Error retrieving DTV Config settings");
         }
      };
   GetMyles(XHRCallback, query, "dtvConfigForm");
   },
   
   
/*************************************************************
 * Forge EPG data download
 *************************************************************/
ForceEPGDownload = function()
   {
   var query = ''
      + 'EIT_SCH GUL -F'
      ;
   
   var XHRCallback = 
      {
      success: function(o)
         {
         if (ParseResponse(o))
            {
            SetInfoMessage("EPG Data Requested", 3000, _ADTCOLOR.GREEN);
            }
         else
            {
            LogMyles("Parse error in DTV Config settings");
            }
         },
      failure: function (o)
         {
         LogMyles("AJAX Error retrieving DTV Config settings");
         }
      };
   SetInfoMessage("Requesting EPG Data... Please wait", 3000, _ADTCOLOR.GOLD);
   SetMyles(XHRCallback, query);
   },
   
   
/*************************************************************
 * Submit DTVguide page data
 *************************************************************/
SubmitDtvConfigForm = function()
   {
   var query = '';
   if(IsJaguar2())
      {
      if(_dtvChanged["address"] || _dtvChanged["serial"])
         {
         query += "EIT_SCH GUL -c \"http://" + $("dtvGuideSrvIpTextfield").value + ":" + $("portTextfield").value + "/dtvGuide/Admin?serial=" + $("dtvUserNameTextfield").value + "&method=getSourceCache\"" + _NEWLINE;
         }
      }
   else if(IsJaguar3())
      {
      if(_dtvChanged["address"])
         {
         query += "EIT_SCH GUL -c " + $("dtvGuideSrvIpTextfield").value + _NEWLINE;
         }
      if(_dtvChanged["serial"] || _dtvChanged["ftppass"])
         {
         query+= 'SYSD CPW ' + $("dtvUserNameTextfield").value + ',' + $("dtvFtpPwdTextfield").value + _NEWLINE;
         }
      }
   else
      {
      }
   if(_dtvChanged["poll"])
      {
      query += "EIT_SCH GUL -p " + $("dtvPollIntervalTextfield").value + _NEWLINE;
      }

   var XHRCallback = 
      {
      success: function(o)
         {
         SetInfoMessage("Your new settings have been set", 3000,_ADTCOLOR.GREEN);
         },
      failure: function(o)
         {
         ResetCursor();
         LogMyles("DTV Config form submit failed. Unable to set new values."         + o.response);   
         }
      };
   SetMyles(XHRCallback, query, true, true, LoadDtvConfig);
   },
   
   
/*************************************************************
 * Validate DTVguide page data
 *************************************************************/
ValidateDtvConfigForm = function
   (
   ) 
   {
   var polInterval = parseInt($("dtvPollIntervalTextfield").value, 10);
  
   if(_dtvChanged["address"] && (!_IPREGEX.test($("dtvGuideSrvIpTextfield").value)))
      {
      SetInfoMessage("Invalid Server Address.", 3000, _ADTCOLOR.RED);
      $("dtvUserNameTextfield").focus();
      return false;
      }
   if(_dtvChanged["address"] && IsJaguar2() && isNaN(parseInt($("portTextfield").value, 10)))
      {
      SetInfoMessage("Invalid Port.", 3000, _ADTCOLOR.RED);
      $("portTextfield").focus();
      return false;
      }
   
   if (_dtvChanged["serial"] && (Trim($("dtvUserNameTextfield").value) == ""))
      {
      SetInfoMessage("Please provide a username.", 3000, _ADTCOLOR.RED);
      $("dtvUserNameTextfield").focus();
      return false;
      }
   
   if (_dtvChanged["poll"]&& ( isNaN(polInterval) || polInterval < (15*_SECONDSPERMINUTE)))
      {
      SetInfoMessage("The minimum polling interval is 900 seconds (15 minutes).", 3000, _ADTCOLOR.RED);
      $("dtvPollIntervalTextfield").focus();
      return false;
      }
   if (_dtvChanged["ftppass"] && (Trim($("dtvFtpPwdTextfield").value) == ""))
      {
      SetInfoMessage("FTP password cannot be blank.", 3000, _ADTCOLOR.RED);
      $("dtvFtpPwdTextfield").focus();
      return false;
      }
   SetInfoMessage("Submitting Form.  Please wait", 3000, _ADTCOLOR.GOLD);
   SubmitDtvConfigForm();
   }
   ;//Starts the Web Application. Ensure that this file is the last one concatenated for every product.
//This will ensure that the entire js content is loaded, before calling any functions contained in it
LoadMyles();   
 