var LMArray ;
var WMTypeArray ;
var EncTypeArray ;
var EncpTypeArray ;
LMArray       = new Array() ;
WMTypeArray   = new Array() ; 
EncTypeArray  = new Array() ;
EncpTypeArray = new Array() ;

// --------------------------------------------------------------------------------------------------------------
// These variables, the SetupEncComb(), EncoderCombSetup() and SetupNextField() functions are help stuff for 
// making implementation of the encoder/parameters/wmtype/price/in_basket check as simple as posible.
// To use it, call SetupEncComb() with the initial values, this can be part of the XML generating the page, and
// when the meta data for Encoders, parameters, wm types and the combinations have been initialized (also 
// normally part of an XML generation (output from GETPURCHASECOMBINATIONS)) then EncoderCombSetup() should be
// called to initialize all of the SELECTs to the default value.
// The interface supports arrays. Pages only displaying one combination will not have to specify
// the arrayindex to any function (index 0 will be default), but if the array is needed all the
// normal calls will have to be extended with an arrayIndex specifyier.
// --------------------------------------------------------------------------------------------------------------
var LMIDArray         = new Array() ;
var combEncIDField    = new Array() ;
var combEncpIDField   = new Array() ;
var combWMTypeField   = new Array() ;
var combLMPriceField  = new Array() ;
var combInBasketField = new Array() ;

// --------------------------------------------------------------------------------------------------------------
// Callback function from the XML generation - saves creating dummy fields for each ID which is 
// actually only use during initialization...
// The encTypeSelect, encpTypeSelect, WMTypeSelect are the controls used for showing the
// encoder/encp//wm types. These were designed to be <select> items, but if only one choice exists
// these may be <td> or <span> objects. The VisPresControl will deal with the actual displaying and
// changing of content if the choice changes.
// --------------------------------------------------------------------------------------------------------------
function SetupEncComb(LM_ID, SL_ID, ENC_ID, ENCP_ID, WM_TYPE_ID, WM_ENCP_ID, 
                      encTypeSelect, encpTypeSelect, WMTypeSelect, LMPriceField, InBasketField,
                      arrayIndx)
{
  var thisIndx = 0 ;
  if (typeof(arrayIndx) != 'undefined')
    // Array index specified?
    thisIndx = arrayIndx ;

  // LMIDArray holds information about the chosen combination of lm_id, wm_encp_id etc.
  // Saves having an array for each type.
  LMIDArray[thisIndx]         = new DLLM(LM_ID, SL_ID, ENC_ID, ENCP_ID, WM_TYPE_ID, WM_ENCP_ID) ;
  combInBasketField[thisIndx] = InBasketField ;
  combEncIDField[thisIndx]    = new VisPresControl(encTypeSelect) ;
  combEncpIDField[thisIndx]   = new VisPresControl(encpTypeSelect) ;
  combWMTypeField[thisIndx]   = new VisPresControl(WMTypeSelect) ;
  combLMPriceField[thisIndx]  = new VisPresControl(LMPriceField) ;
}

// --------------------------------------------------------------------------------------------------------------
// This function is to be called after the metadata for encoder/parameter/wmtypes has been initialized. This
// function then selects the combination defined by combEncID/combEncpID/combWMType in the SELECTS.
// Also, initiates the checkbox/shopcart system with the combination chosen.
// --------------------------------------------------------------------------------------------------------------
function EncoderCombSetup(arrayIndx)
{
  var thisIndx = 0 ;
  if (typeof(arrayIndx) != 'undefined')
    thisIndx = arrayIndx ;

  var chosenComb = 
    SetupEncType(LMIDArray[thisIndx].GetLMID(),
                 combEncIDField[thisIndx],
                 combEncpIDField[thisIndx],
                 combWMTypeField[thisIndx],
                 combLMPriceField[thisIndx],
                 LMIDArray[thisIndx].GetENCID(),
                 LMIDArray[thisIndx].GetENCPID(),
                 LMIDArray[thisIndx].GetWMTYPEID()) ;

  if (combInBasketField[thisIndx] != null)
    CheckLM(combInBasketField[thisIndx], LMIDArray[thisIndx].GetLMID(),
            chosenComb.GetWMENCPID(), LMIDArray[thisIndx].GetSLID(), chosenComb.GetUOTID()) ;


  // Disable the combo boxes if the chosen LM only exists in 1 encoding anyway...
  if (DisableIfOne(combEncIDField[thisIndx]) == true)
    if (DisableIfOne(combEncpIDField[thisIndx]) == true)
      DisableIfOne(combWMTypeField[thisIndx]) ;
}                             


// --------------------------------------------------------------------------------------------------------------
function SetupNextSelect(thisSelect, arrayIndx)
{
  var chosenComb = null ;
  var thisIndx = 0 ;
  if (typeof(arrayIndx) != 'undefined')
    thisIndx = arrayIndx ;
  
  if (thisSelect == 1)
    chosenComb = 
      SetupParamsType(LMIDArray[thisIndx].GetLMID(),
                      combEncIDField[thisIndx], 
                      combEncpIDField[thisIndx], 
                      combWMTypeField[thisIndx], 
                      combLMPriceField[thisIndx]) ;
  else if (thisSelect == 2)
    chosenComb = 
      SetupWMType(LMIDArray[thisIndx].GetLMID(), 
                  combEncIDField[thisIndx], 
                  combEncpIDField[thisIndx], 
                  combWMTypeField[thisIndx], 
                  combLMPriceField[thisIndx]) ;
  else
    chosenComb = 
      SetPrice(LMIDArray[thisIndx].GetLMID(),
               combEncIDField[thisIndx], 
               combEncpIDField[thisIndx], 
               combWMTypeField[thisIndx], 
               combLMPriceField[thisIndx]) ;
               
  if (chosenComb != null)                
    CheckLM(combInBasketField[thisIndx], LMIDArray[thisIndx].GetLMID(),
            chosenComb.GetWMENCPID(), LMIDArray[thisIndx].GetSLID(), chosenComb.GetUOTID()) ;
}

// --------------------------------------------------------------------------------------------------------------
// Disables the passed combo box if it holds only entry and returns true.
// Otherwise returns false.
// --------------------------------------------------------------------------------------------------------------
function DisableIfOne(visPresControl)
{
  if (visPresControl.GetListLength() > 1)
    return (false) ;
  else
  {
    visPresControl.Disable() ;
    return (true) ;
  }
}

// Return the VisControl object that encapsulates the price field. Used if the caller needs to
// check the current price (cart/view.htm).
function GetPriceVisControl(arrayIndx)
{
  if (typeof(arrayIndx) != 'undefined')
    return (combLMPriceField[arrayIndx]) ;
  else
    return (combLMPriceField[0]) ;
}

// --------------------------------------------------------------------------------------------------------------
// Start of the internal works.
// --------------------------------------------------------------------------------------------------------------

// --------------------------------------------------------------------------------------------------------------
// Initializes a particular combination of LM_ID/ENCODER/ENCODER PARAMS/WATERMARK(/PRICE/UOT_ID).
// --------------------------------------------------------------------------------------------------------------
function CombInit(LM_ID, ENC_ID, ENCP_ID, WM_ID, PRICE, WM_ENCP_ID, UOT_ID) 
{
  var LMObj ;
  LMObj = AddNewToArray(LM_ID, LMArray, LMInf) ;
  LMObj.AddEncoder(ENC_ID, ENCP_ID, WM_ID, PRICE, WM_ENCP_ID, UOT_ID) ;
}

// --------------------------------------------------------------------------------------------------------------
// Functions for setting up the SELECTs that holds the valid Encoders/Parameters/WMTypes for a particular LM_ID.
// --------------------------------------------------------------------------------------------------------------
// Note, the Chosen... parameters are optional - if present, the entry in the SELECT denoted by the passed 
// ID is selected.
// These functions returns the WM_ENCP_ID/UOT_ID (ChosenEncpComb object) that corresponds to the chosen combination.
// --------------------------------------------------------------------------------------------------------------
function SetupEncType(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl,
                      chosenEncID, chosenENCPID, chosenWMID)
{
  var Encoders ;
  var LMObj ;

  LMObj = GetLMObj(LM_ID) ;
  Encoders = LMObj.GetEncoders() ;

  encTypeVisControl.PresentList(Encoders, chosenEncID) ; // FillCombo(Encoders, encTypeSelect, chosenEncID) ;
  return (SetupParamsType(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl, chosenENCPID, chosenWMID)) ;
}
// Function for setting up the SELECT that holds the valid Encoder params for the chosen Encoder
// In turn, alse sets up the WaterMark SELECT.
function SetupParamsType(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl, 
                         chosenENCPID, chosenWMID)
{
  var Encoders ;
  var Params ;
  var chosenEncoder ;
  var LMObj ;

  LMObj = GetLMObj(LM_ID) ;

  chosenEncoder = encTypeVisControl.GetSelectedIndx() ; // chosenEncoder = 0 + encTypeSelect.selectedIndex ; // <<-- index!
  Encoders = LMObj.GetEncoders() ;
  Params = Encoders[chosenEncoder].GetParams() ;
  encpTypeVisControl.PresentList(Params, chosenENCPID) ; //  FillCombo(Params, encpTypeSelect, chosenENCPID) ;
  return (SetupWMType(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl, chosenWMID)) ;
}
// Function for setting up the SELECT that holds the valid WaterMark types for the chosen Encoder/Parameter for the LM_ID.
function SetupWMType(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl, chosenWMID)
{
  var Encoders ;
  var Params ;
  var WaterMarks ;
  var chosenEncoder ;
  var chosenParam ;
  var LMObj ;

  LMObj = GetLMObj(LM_ID) ;

  chosenEncoder = encTypeVisControl.GetSelectedIndx() ; // chosenEncoder = 0 + encTypeSelect.selectedIndex ; // <<-- index!
  chosenParam = encpTypeVisControl.GetSelectedIndx() ; // chosenParam = 0 + encpTypeSelect.selectedIndex ; // <<-- index! 

  Encoders = LMObj.GetEncoders() ;
  Params = Encoders[chosenEncoder].GetParams() ;
  WaterMarks = Params[chosenParam].GetWaterMarks() ;

  WMTypeVisControl.PresentList(WaterMarks, chosenWMID) ; // FillCombo(WaterMarks, WMTypeSelect, chosenWMID) ;
  return (SetPrice(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl)) ;
}
// Function for setting the price field based on the current selection of Encoder/Encoder Parameters/WaterMark
function SetPrice(LM_ID, encTypeVisControl, encpTypeVisControl, WMTypeVisControl, LMPriceVisControl)
{
  var Encoders ;
  var Params ;
  var WaterMarks ;
  var chosenEncoder ;
  var chosenParam ;
  var chosenWM ;
  var LMObj ;
 
  LMObj = GetLMObj(LM_ID) ;

  chosenEncoder = encTypeVisControl.GetSelectedIndx() ; // chosenEncoder = 0 + encTypeSelect.selectedIndex ; // <<-- index!
  chosenParam   = encpTypeVisControl.GetSelectedIndx() ; // chosenParam = 0 + encpTypeSelect.selectedIndex ; // <<-- index! 
  chosenWM      = WMTypeVisControl.GetSelectedIndx() ; // chosenWM = 0 + WMTypeSelect.selectedIndex ; // <<-- index!

  Encoders = LMObj.GetEncoders() ;
  Params = Encoders[chosenEncoder].GetParams() ;
  WaterMarks = Params[chosenParam].GetWaterMarks() ;
  LMPriceVisControl.SetValue(WaterMarks[chosenWM].GetPrice()) ; // LMPriceField.value = WaterMarks[chosenWM].GetPrice() ;
  
  var chosenEncpCombination = new ChosenEncpComb(WaterMarks[chosenWM].GetWMENCPID(),
                                                 WaterMarks[chosenWM].GetUOTID()) ;
                                                 
  return (chosenEncpCombination) ; // Return WM_ENCP_ID and UOT_ID of the chosen combination.
}

// --------------------------------------------------------------------------------------------------------------
// Function for obtaining the WM_ENCP_ID for the currently chosen combination of Encoder/Params/WM.  
// --------------------------------------------------------------------------------------------------------------
function GetCurrentENCPID(LM_ID, arrayIndx)
{
  var Encoders ;
  var Params ;
  var WaterMarks ;
  var chosenEncoder ;
  var chosenParam ;
  var chosenWM ;
  var LMObj ;
  var thisIndx = 0 ;

  if (typeof(arrayIndx) != 'undefined')
    thisIndx = arrayIndx ;


  LMObj = GetLMObj(LM_ID) ;

  chosenEncoder = combEncIDField[thisIndx].GetSelectedIndx() ;
  chosenParam   = combEncpIDField[thisIndx].GetSelectedIndx() ;
  chosenWM      = combWMTypeField[thisIndx].GetSelectedIndx() ;
   
  Encoders    = LMObj.GetEncoders() ;
  Params      = Encoders[chosenEncoder].GetParams() ;
  WaterMarks  = Params[chosenParam].GetWaterMarks() ;

  var chosenEncpCombination = new ChosenEncpComb(WaterMarks[chosenWM].GetWMENCPID(),
                                                 WaterMarks[chosenWM].GetUOTID()) ;
                                                 
  return (chosenEncpCombination) ; // Return WM_ENCP_ID and UOT_ID of the chosen combination.
}

// --------------------------------------------------------------------------------------------------------------
// Aux. function for finding a LM in the array of LM objects.
// --------------------------------------------------------------------------------------------------------------
function GetLMObj(LM_ID)
{
  var g ;
  for (g = 0 ; g < LMArray.length ; g++)
    if (LMArray[g].GetID() == LM_ID)
      return (LMArray[g]) ;

  return (null) ;
}

// --------------------------------------------------------------------------------------------------------------
// ------------- These are the objects that holds the static lists of the different TYPES (Encoder, Parameters, WaterMark) ---------
// Watermark TYPE.
// --------------------------------------------------------------------------------------------------------------
function WMTypeInit(WM_TYPE_ID, Description)
{
  WMTypeArray[WMTypeArray.length] = new WMType(WM_TYPE_ID, Description) ;
}
function GetWMObj(WM_TYPE_ID)
{
  var g ;
  for (g = 0 ; g < WMTypeArray.length ; g++)
    if (WMTypeArray[g].GetID() == WM_TYPE_ID)
      return (WMTypeArray[g]) ;

  return (null) ;      
}
function WMType(WM_TYPE_ID, Description)
{
  if (typeof(WMTypeDeclared) == 'undefined')
    protoWMType() ;
  this.Init(WM_TYPE_ID, Description) ;
}
function protoWMType()
{
  WMTypeDeclared = true ;
  WMType.prototype.Init     = _WMTInit ;
  WMType.prototype.GetID    = _WMTGetID ;
  WMType.prototype.GetDesc  = _WMTGetDesc ;
}
function _WMTInit(WM_TYPE_ID, Description)
{
  this.WMTypeID   = WM_TYPE_ID ;
  this.Description  = Description ;
}
function _WMTGetID()
{
  return (this.WMTypeID) ;
}
function _WMTGetDesc()
{
  return (this.Description) ;
}
// --------------------------------------------------------------------------------------------------------------
// Encoder TYPE.
// --------------------------------------------------------------------------------------------------------------
function EncoderTypeInit(ENC_ID, Description, Name)
{
  EncTypeArray[EncTypeArray.length] = new EncType(ENC_ID, Description, Name) ;
}
function GetEncTypeObj(ENC_ID)
{
  var g ;
  for (g = 0 ; g < EncTypeArray.length ; g++)
    if (EncTypeArray[g].GetID() == ENC_ID)
      return (EncTypeArray[g]) ;

  return (null) ;      
}
function EncType(ENC_ID, Description, Name)
{
  if (typeof(EncTypeDeclared) == 'undefined')
    protoEncType() ;
  this.Init(ENC_ID, Description, Name) ;
}
function protoEncType()
{
  EncTypeDeclared = true ;
  EncType.prototype.Init        = _ETInit ;
  EncType.prototype.GetID       = _ETGetID ;
  EncType.prototype.GetDesc     = _ETGetEncName ; // default description = name!
  EncType.prototype.GetEncName  = _ETGetEncName ;
  EncType.prototype.GetEncDesc  = _ETGetEncDesc ;
}
function _ETInit(ENC_ID, Description, Name)
{
  this.Enc_ID       = ENC_ID ;
  this.Description  = Description ;
  this.Name         = Name ;
}
function _ETGetID()
{
  return (this.Enc_ID) ;
}
function _ETGetEncDesc()
{
  return (this.Description) ;
}
function _ETGetEncName()
{
  return (this.Name) ;
}
// --------------------------------------------------------------------------------------------------------------
// Parameters TYPE.
// --------------------------------------------------------------------------------------------------------------
function EncParameterInit(ENC_ID, ENCP_ID, Quality, Bitrate)
{
  EncpTypeArray[EncpTypeArray.length] = new EncParameterType(ENCP_ID, Quality, Bitrate) ;
}
function GetParameterObj(ENCP_ID)
{
  var g ;
  for (g = 0 ; g < EncpTypeArray.length ; g++)
    if (EncpTypeArray[g].GetID() == ENCP_ID)
      return (EncpTypeArray[g]) ;

  return (null) ;      
}
function EncParameterType(ENCP_ID, Quality, Bitrate)
{
  if (typeof(EncParameterTypeDeclared) == 'undefined')
    protoEncParameterType() ;
  this.Init(ENCP_ID, Quality, Bitrate) ;
}
function protoEncParameterType()
{
  EncParameterTypeDeclared = true ;
  EncParameterType.prototype.Init        = _EPTInit ;
  EncParameterType.prototype.GetID       = _EPTGetID ;
//  EncParameterType.prototype.GetDesc     = _EPTGetQuality ; // <-- default description = Quality!
  EncParameterType.prototype.GetDesc     = _EPTGetBitrate ; // <-- default description = Bitrate!
  EncParameterType.prototype.GetQuality  = _EPTGetQuality ;
  EncParameterType.prototype.GetBitrate  = _EPTGetBitrate ;
}
function _EPTInit(ENCP_ID, Quality, Bitrate)
{
  this.ENCP_ID      = ENCP_ID ;
  this.Quality      = Quality ;
  this.Bitrate      = Bitrate ;
}
function _EPTGetID()
{
  return (this.ENCP_ID) ;
}
function _EPTGetQuality()
{
  return (this.Quality) ;
}
function _EPTGetBitrate()
{
  return (this.Bitrate) ;
}

// --------------------------------------------------------------------------------------------------------------
// Object for storing the actual LM with associated ENCODERs/ENCODER PARAMETERs/WATERMARKs and PRICE
// --------------------------------------------------------------------------------------------------------------
function LMInf(LM_ID) 
{
  if (typeof(LMInfDefined) == 'undefined') 
    protoLMInf() ;

  this.Init(LM_ID) ;
}
function protoLMInf()
{
  LMInfDefined = true ;
  LMInf.prototype.Init          = _LIDInit ;
  LMInf.prototype.GetID         = _LIDGetLMID ;
  LMInf.prototype.AddEncoder    = _LIDAddEncoder ;
  LMInf.prototype.GetEncoders   = _LIDGetEncoders ;
}
function _LIDInit(LM_ID)
{
  this.LM_ID =  LM_ID ;
  this.EncoderArr = new Array() ;
}
function _LIDGetLMID()
{
  return (this.LM_ID) ;
}
function _LIDAddEncoder(ENC_ID, ENCP_ID, WM_ID, PRICE, WM_ENCP_ID, UOT_ID)
{
  var encObj ;
  encObj = AddNewToArray(ENC_ID, this.EncoderArr, Encoder) ;
  encObj.AddParameter(ENCP_ID, WM_ID, PRICE, WM_ENCP_ID, UOT_ID) ;
}
function _LIDGetEncoders()
{
  return (this.EncoderArr) ;
}

// --------------------------------------------------------------------------------------------------------------
// Class for holding Encoder information for a particular LM. Holds the ID of the encoder and the valid 
// Encoder parameters (bitrates).
// --------------------------------------------------------------------------------------------------------------
function Encoder(ENC_ID)
{
  if (typeof(EncoderDefined ) == 'undefined') 
    protoEncoder() ;
  this.Init(ENC_ID) ;
}
function protoEncoder()
{
  EncoderDefined = true ;
  Encoder.prototype.Init          = _EInit ;
  Encoder.prototype.GetID         = _EGetEncID ;
  Encoder.prototype.GetDesc       = _EGetEncDesc ;
  Encoder.prototype.AddParameter  = _EAddParameter ;
  Encoder.prototype.GetParams     = _EGetParameters ;
}
function _EInit(ENC_ID) 
{
  this.ENC_ID = ENC_ID ;
  this.ParameterArray = new Array() ;
  this.EncoderTypeObj = GetEncTypeObj(ENC_ID) ;
}
function _EGetEncID()
{
  return (this.ENC_ID) ;
}
function _EGetEncDesc()
{
  return (this.EncoderTypeObj.GetDesc()) ;
}
function _EAddParameter(ENCP_ID, WM_ID, Price, WM_ENCP_ID, UOT_ID) 
{
  var thisParameter ;
  thisParameter = AddNewToArray(ENCP_ID, this.ParameterArray, EncParameter, WM_ENCP_ID) ;
  thisParameter.AddWM(WM_ID, Price, WM_ENCP_ID, UOT_ID) ;
}
function _EGetParameters()
{
  return (this.ParameterArray) ;
}
// --------------------------------------------------------------------------------------------------------------
// Class for holding the encoding parameters of a particular LM/Encoding type. Adds information of which 
// watermarks are valid for the track.
// --------------------------------------------------------------------------------------------------------------
function EncParameter(ENCP_ID)
{
  if (typeof(EncParameterDefined) == 'undefined')
    protoEncParameter() ;
  this.Init(ENCP_ID) ;
}
function protoEncParameter()
{
  EncParameterDefined = true ;
  EncParameter.prototype.Init          = _EPInit ;
  EncParameter.prototype.AddWM         = _EPAddWM ;
  EncParameter.prototype.GetID         = _EPGetID ;
  EncParameter.prototype.GetDesc       = _EPGetDesc ;
  EncParameter.prototype.GetWaterMarks = _EPGetWaterMarks ;
}
function _EPInit(ENCP_ID) 
{
  this.ENCP_ID = ENCP_ID ;
  this.WMArray = new Array() ;
  // Get a pointer to the object describing this Encoding Parameter (from the list of all Encoding Parameters)
  this.ParameterObj = GetParameterObj(ENCP_ID) ;
}
function _EPAddWM(WM_ID, Price, WM_ENCP_ID, UOT_ID)
{
  var thisWM ;
  thisWM = AddNewToArray(WM_ID, this.WMArray, WaterMark) ;
  thisWM.SetPrice(Price) ;
  thisWM.SetUOTID(UOT_ID) ;
  thisWM.SetWMENCPID(WM_ENCP_ID) ;
}
function _EPGetID()
{
  return (this.ENCP_ID) ;
}
function _EPGetDesc()
{
  return (this.ParameterObj.GetDesc()) ;
}
function _EPGetWaterMarks()
{
  return (this.WMArray) ;
}
// --------------------------------------------------------------------------------------------------------------
// Function for holding information for a watermark. Adds information about the price of this particular 
// combination of LM/ENCODER/ENCODER PARAMETERS/WATERMARK.
// --------------------------------------------------------------------------------------------------------------
function WaterMark(WM_ID)
{
  if (typeof(WaterMarkDefined) == 'undefined')
    protoWaterMark() ;
  this.Init(WM_ID) ;
}
function protoWaterMark()
{
  WaterMarkDefined = true ;
  WaterMark.prototype.Init        = _WMInit ;
  WaterMark.prototype.GetID       = _WMGetID ;
  WaterMark.prototype.GetDesc     = _WMGetDesc ;
  WaterMark.prototype.SetPrice    = _WMSetPrice ;
  WaterMark.prototype.SetUOTID    = _WMSetUOTID ;
  WaterMark.prototype.SetWMENCPID = _WMSetWMENCPID ;
  WaterMark.prototype.GetPrice    = _WMGetPrice ;
  WaterMark.prototype.GetUOTID    = _WMGetUOTID ;
  WaterMark.prototype.GetWMENCPID = _WMGetWMENCPID ;
}
function _WMInit(WM_ID)
{
  this.WM_ID = WM_ID ;
  this.Price = 0 ;
  this.WM_ENCP_ID = 0 ;
  this.UOT_ID = 0 ;  
  // Get a pointer to the object describing this WaterMark (from the list of all WaterMarks)
  this.WMObj = GetWMObj(WM_ID) ;
}
function _WMGetID()
{
  return (this.WM_ID) ;
}
function _WMGetDesc()
{
  return (this.WMObj.GetDesc()) ;
}
function _WMSetPrice(Price) 
{
  this.Price = Price ;
}
function _WMGetPrice() 
{
  return (this.Price) ;
}
function _WMSetUOTID(UOT_ID) 
{
  this.UOT_ID = UOT_ID ;
}
function _WMGetUOTID() 
{
  return (this.UOT_ID) ;
}
function _WMSetWMENCPID(WM_ENCP_ID) 
{
  this.WM_ENCP_ID = WM_ENCP_ID ;
}
function _WMGetWMENCPID() 
{
  return (this.WM_ENCP_ID) ;
}

// --------------------------------------------------------------------------------------------------------------
// Objects for presenting the encoder/quality/watermark choices on the screen. Hides the details of
// the control being used (select/td/span/text/*none*) from the caller.
// The HTLM element to use must be passed upon initialization. If no element is to be displayed,
// then null can be passed. This will create a "dummy" object that just holds the state of the
// non-existing HTML element.
// The entry function is VisPresControl() which determines what object to handle *this*
// presentation, based on the type of htmlElement.
// --------------------------------------------------------------------------------------------------------------
function VisPresControl(htmlElement)
{
  var elementType ;

  if (htmlElement == null)
  {
    // No visible element for this "item". Create a "dummy".
    return (new NonVisPresControl(htmlElement)) ;
  }
  else
  {
    if (typeof(htmlElement.type) != 'undefined')
      elementType =  htmlElement.type ; // "select one" for <select>
    else
      elementType = '' ; // <td> (and <span>?) elements
    elementType = elementType.toLowerCase() ; // JIC

    if (elementType.indexOf('select') > -1)
      return (new SelectVisPresControl(htmlElement)) ;
    else if (elementType.indexOf('text') > -1 || elementType.indexOf('hidden') > -1)
      return (new TextVisPresControl(htmlElement)) ;
    else
      return (new TDVisPresControl(htmlElement)) ;
  }
}

// This is the class for presenting the list of choices in a combobox (<SELECT> element).
function SelectVisPresControl(htmlElement)
{
  if (typeof(SelectVisPresControlDefined) == 'undefined')
    _protoSelectVisPresControl() ;
  this.Init(htmlElement) ;
}
function _protoSelectVisPresControl()
{
  SelectVisPresControlDefined                     = true ;
  SelectVisPresControl.prototype.Init             = svpcInit ;
  SelectVisPresControl.prototype.PresentList      = svpcPresentList ;
  SelectVisPresControl.prototype.GetSelectedIndx  = svpcGetSelectedIndx ;
  SelectVisPresControl.prototype.Disable          = svpcDisableControl ;
  SelectVisPresControl.prototype.GetListLength    = svpcGetListLength ;
  SelectVisPresControl.prototype.SetValue         = svpcSetValue ;
  SelectVisPresControl.prototype.GetValue         = svpcGetValue ;
}
function svpcInit(htmlElement) 
{
  this.selectFld = htmlElement ;
}
function svpcPresentList(valuesArray, selectedValue)
{
  FillCombo(valuesArray, this.selectFld, selectedValue) ;
}
function svpcSetValue(newValue)
{
  // Make a dummy array with only this value.
  var valuesArray = new Array() ;
  valuesArray[0] = new SimpleOption(newValue) ; // make a dummy object that FillCombo can work on.
  FillCombo(valuesArray, this.selectFld, newValue) ;
}
function svpcGetSelectedIndx()
{
  return (this.selectFld.selectedIndex) ;
}
function svpcDisableControl()
{
  this.selectFld.disabled = true ;
}
function svpcGetListLength()
{
  return (this.selectFld.length) ;
}
function svpcGetValue()
{
  return (this.selectFld.value) ;
}

// This is the class for presenting the list of choices in a string (inside a <TD> element).
// The list can only consist of one element (!)
function TDVisPresControl(htmlElement)
{
  if (typeof(TDVisPresControlDefined) == 'undefined')
    _protoTDVisPresControl() ;
  this.Init(htmlElement) ;
}
function _protoTDVisPresControl()
{
  TDVisPresControlDefined                     = true ;
  TDVisPresControl.prototype.Init             = tvpcInit ;
  TDVisPresControl.prototype.PresentList      = tvpcPresentList ;
  TDVisPresControl.prototype.GetSelectedIndx  = tvpcGetSelectedIndx ;
  TDVisPresControl.prototype.Disable          = tvpcDisableControl ;
  TDVisPresControl.prototype.GetListLength    = tvpcGetListLength ;
  TDVisPresControl.prototype.SetValue         = tvpcSetValue ;
  TDVisPresControl.prototype.GetValue         = tvpcGetValue ;
}
function tvpcInit(htmlElement) 
{
  this.selectFld      = htmlElement ;
  this.listLength     = 0 ;
  this.selectedValue  = '' ;
}
function tvpcPresentList(valuesArray, selectedValue)
{
  // The list can only consist of one element.
  this.listLength = valuesArray.length ;
  if (this.listLength > 0)
  {
    this.selectFld.innerHTML = valuesArray[0].GetDesc() ;
    this.selectedValue       = valuesArray[0].GetID() ;
  }
  else
  {
    this.selectFld.innerHTML = '' ;
    this.selectedValue = '' ;
  }
}
function tvpcSetValue(newValue)
{
  this.selectFld.innerHTML = newValue ;
  this.selectedValue       = newValue ;
}
function tvpcGetValue()
{
  return (this.selectedValue) ;
}
function tvpcGetSelectedIndx()
{
  return (0) ;
}
function tvpcDisableControl()
{
  // cannot disable a text control...
}
function tvpcGetListLength()
{
  // There can maximum be one element in the list.
  return (this.listLength) ;
}
// This is the class for presenting the list of choices in a string (inside a <TEXT> element).
// The list can only consist of one element (!)
function TextVisPresControl(htmlElement)
{
  if (typeof(TextVisPresControlDefined) == 'undefined')
    _protoTextVisPresControl() ;
  this.Init(htmlElement) ;
}
function _protoTextVisPresControl()
{
  TextVisPresControlDefined                     = true ;
  TextVisPresControl.prototype.Init             = txtvpcInit ;
  TextVisPresControl.prototype.PresentList      = txtvpcPresentList ;
  TextVisPresControl.prototype.GetSelectedIndx  = txtvpcGetSelectedIndx ;
  TextVisPresControl.prototype.Disable          = txtvpcDisableControl ;
  TextVisPresControl.prototype.GetListLength    = txtvpcGetListLength ;
  TextVisPresControl.prototype.SetValue         = txtvpcSetValue ;
  TextVisPresControl.prototype.GetValue         = txtvpcGetValue ;
}
function txtvpcInit(htmlElement) 
{
  this.selectFld      = htmlElement ;
  this.listLength     = 0 ;
  this.selectedValue  = '' ;
}
function txtvpcPresentList(valuesArray, selectedValue)
{
  // The list can only consist of one element.
  this.listLength = valuesArray.length ;
  if (this.listLength > 0)
  {
    this.selectFld.value     = valuesArray[0].GetDesc() ;
    this.selectedValue       = valuesArray[0].GetID() ;
  }
  else
  {
    this.selectFld.value = '' ;
    this.selectedValue   = '' ;
  }
}
function txtvpcSetValue(newValue) 
{
  this.selectFld.value = newValue ;
  this.selectedValue   = newValue ;
}
function txtvpcGetValue()
{
  return (this.selectFld.value) ;
}
function txtvpcGetSelectedIndx()
{
  return (0) ;
}
function txtvpcDisableControl()
{
  // We don't disable text fields, only make them read-only.
  this.selectFld.readOnly = true ;
}
function txtvpcGetListLength()
{
  // There can maximum be one element in the list.
  return (this.listLength) ;
}

// This is the class for just holding the state of an list without any visual object.
// The list can only consist of one element (!)
function NonVisPresControl(htmlElement)
{
  if (typeof(NonVisPresControlDefined) == 'undefined')
    _protoNonVisPresControl() ;
  this.Init() ;
}
function _protoNonVisPresControl()
{
  NonVisPresControlDefined                     = true ;
  NonVisPresControl.prototype.Init             = nvpcInit ;
  NonVisPresControl.prototype.PresentList      = nvpcPresentList ;
  NonVisPresControl.prototype.GetSelectedIndx  = nvpcGetSelectedIndx ;
  NonVisPresControl.prototype.Disable          = nvpcDisableControl ;
  NonVisPresControl.prototype.GetListLength    = nvpcGetListLength ;
  NonVisPresControl.prototype.SetValue         = nvpcSetValue ;
  NonVisPresControl.prototype.GetValue         = nvpcGetValue ;
}
function nvpcInit(htmlElement) 
{
  this.selectFld      = '' ; // no actual visual element to show state in, "use" internal variable...
  this.listLength     = 0 ;
  this.selectedValue  = '' ;
}
function nvpcPresentList(valuesArray, selectedValue)
{
  // The list can only consist of one element.
  this.listLength = valuesArray.length ;
  if (this.listLength > 0)
  {
    this.selectFld           = valuesArray[0].GetDesc() ;
    this.selectedValue       = valuesArray[0].GetID() ;
  }
  else
  {
    this.selectFld       = '' ;
    this.selectedValue   = '' ;
  }
}
function nvpcSetValue(newValue) 
{
  this.selectFld       = newValue ;
  this.selectedValue   = newValue ;
}
function nvpcGetValue() 
{
  return (this.selectedValue) ;
}
function nvpcGetSelectedIndx()
{
  return (0) ;
}
function nvpcDisableControl()
{
  // no visual element to disable...
}
function nvpcGetListLength()
{
  // There can maximum be one element in the "list".
  return (this.listLength) ;
}

// --------------------------------------------------------------------------------------------------------------
// Utility object for returning wm_encp_id/uot_id combination currently chosen.
// --------------------------------------------------------------------------------------------------------------
function ChosenEncpComb(WM_ENCP_ID, UOT_ID)
{
  if (typeof(ChosenEncpCombDefined) == 'undefined') 
    _protoChosenEncpComb() ;
  this.Init(WM_ENCP_ID, UOT_ID) ;
}
function _protoChosenEncpComb()
{
  ChosenEncpCombDefined                = true ;
  ChosenEncpComb.prototype.Init        = CECInit ;
  ChosenEncpComb.prototype.GetENCPID   = CECGetWMENCPID ;
  ChosenEncpComb.prototype.GetWMENCPID = CECGetWMENCPID ;
  ChosenEncpComb.prototype.GetUOTID    = CECGetUOTID ;
  
}
function CECInit(WM_ENCP_ID, UOT_ID)
{
  this.WM_ENCP_ID = WM_ENCP_ID ;
  this.UOT_ID = UOT_ID ;
}
function CECGetWMENCPID()
{
  return (this.WM_ENCP_ID) ;
}
function CECGetUOTID()
{
  return (this.UOT_ID) ;
}

// ----------------------------------------------------------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------------------------------------------------------
function DLLM(LM_ID, SL_ID, ENC_ID, ENCP_ID, WM_TYPE_ID, UOT_ID, WM_ENCP_ID)
{
  if (typeof(DLLMDefined) == 'undefined')
    protoDLLM() ;
  this.Init(LM_ID, SL_ID, ENC_ID, ENCP_ID, WM_TYPE_ID, UOT_ID, WM_ENCP_ID) ;
}
function protoDLLM()
{
  DLLMDefined = true ;
  DLLM.prototype.Init         = _DLLMInit ;
  DLLM.prototype.GetLMID      = _DLLMGetID ;
  DLLM.prototype.GetSLID      = _DLLMGetSLID ;
  DLLM.prototype.GetWMTYPEID  = _DLLMGetWMTypeID ;
  DLLM.prototype.GetENCID     = _DLLMGetENCID ;
  DLLM.prototype.GetENCPID    = _DLLMGetENCPID ;
  DLLM.prototype.GetWMENCPID  = _DLLMGetWMENCPID ;
}
function _DLLMInit(LM_ID, SL_ID, ENC_ID, ENCP_ID, WM_TYPE_ID, UOT_ID, WM_ENCP_ID)
{
  this.LM_ID      = LM_ID ;
  this.SL_ID      = SL_ID ;
  this.ENC_ID     = ENC_ID ;
  this.ENCP_ID    = ENCP_ID ;
  this.WM_TYPE_ID = WM_TYPE_ID ;
  this.WM_ENCP_ID = WM_ENCP_ID ;
}
function _DLLMGetID()
{
  return (this.LM_ID) ;
}
function _DLLMGetSLID()
{
  return (this.SL_ID) ;
}
function _DLLMGetWMTypeID()
{
  return (this.WM_TYPE_ID) ;
}
function _DLLMGetENCID()
{
  return (this.ENC_ID) ;
}
function _DLLMGetENCPID()
{
  return (this.ENCP_ID) ;
}
function _DLLMGetWMENCPID()
{
  return (this.WM_ENCP_ID) ;
}

// --------------------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------------------
function AddNewToArray(uniqueID, objArray, objType)
{
  var newObj ;
  var g ;
  for (g = 0 ; g < objArray.length ; g++)
    if (objArray[g].GetID() == uniqueID)
      break ;
  if (g >= objArray.length)
    objArray[g] = new objType(uniqueID) ;

  return (objArray[g]) ;
}

// --------------------------------------------------------------------------------------------------------------
function SimpleOption(optValue) 
{
  if (typeof(SimpleOptionDefined) == 'undefined')
    _protoSimpleOption() ;
  this.Init(optValue) ;
}
function _protoSimpleOption()
{
  SimpleOptionDefined = true ;
  SimpleOption.prototype.Init    = soInit ;
  SimpleOption.prototype.GetDesc = soGetDesc ;
  SimpleOption.prototype.GetID   = soGetDesc ; // same as GetDesc().
}
function soInit(optValue)
{
  this.optValue = optValue ;
}
function soGetDesc()
{
  return (this.optValue) ;
}