/***
 * InStoreItem(smart, upcArray, useSmart)
 *
 *  DESCRIPTION
 *    Creates an instance of an InStoreItem object.
 *    This constructor takes a mandatory SMART instance and a 
 *    mandatory array of Item UPC(s). Note that the array consists 
 *    of UPC(s) for the SAME item. Some cell phones have multiple 
 *    UPCs associated with the same item/model. For other items 
 *    like CDs, you only have one UPC per Item, so your array 
 *    size = 1 in those cases.
 *
 *    The boolean useSMART is optional and is true by default. 
 *    Passing "false" will disable querying of the SMART, used 
 *    in instances when the kiosk is set to not use the SMART 
 *    and you need to construct an InStoreItem and set the 
 *    properties manually.
 *
 *  SYNOPSIS:  
 *    InStoreItem([SMART instance], [array of Item UPCs] [, optional useSMART boolean])
 *
 *  EXAMPLE:
 *    (SMART being queried)
 *    var _smart = new Smart("111.111.111.111");
 *    var _isiArr = new Array("0001223611647","0001223611643");
 *    var _item = new InStoreItem(_smart,_isiArr);
 *
 *    (SMART not being queried)
 *    var _isiArr = new Array("0001223611647","0001223611643");
 *    var _item = new InStoreItem(_smart,_isiArr, false);
 *
 *    NOTE: there is a global SMART_HOST javascript constant created in begin_nav
 *    which you can use to pass to your SMART object:
 *    
 *      eg. var _smart = new Smart(SMART_HOST);
 *
 * INSTANCE METHODS
 *  getInItemFile()
 *    returns inItemFile
 *
 *  getUpc()
 *    returns upc
 *
 *  getOnhand()
 *    returns onhand
 *
 *  getPrice()
 *    returns price
 *
 *  getName()
 *    returns name
 *
 *  getReplenishable()
 *    returns replenishable
 *
 *  getTaxFlags()
 *    returns taxflags
 *
 *  isSoldInStore()
 *    returns true if item is onhand or
 *    replenishable flag = Y
 *
 *  getClassName()
 *    returns class name
 *
 *  toString()
 *    returns string dump of object
 *
 *  getIsTimeout()
 *    returns a boolean
 *
 *  setIsTimeout( boolean )
 *    set a boolean value (typically only used to set to true)
 *
 * CLASS METHODS
 *  isOnhand(onhand)
 *    returns [true|false]
 *
 *  isReplenishable(replen)
 *    returns [true|false]
 *
 *  isValidPrice(price)
 *    returns true if price is valid
 **/
function InStoreItem (smart,upcArr,useSmart)
{
  this.useSmart = (useSmart == false) ? false : true;

  /* -- Begin get SMART instance -- */
  Log.logBeginTaskScope( "getting SMART instance.", this.URI );
  try
  {
    if (smart === undefined) 
    {
      throw new Error("Mandatory SMART instance argument is undefined.");
    }
  }
  catch (e)
  {
    Log.logErrorScope( "Smart is null.", this.URI, e );
  }
  Log.logCompletedTaskScope( "getting SMART instance.", this.URI );
  this.smart = smart;
  /* -- End get SMART instance -- */

  /* -- Begin get UPC array -- */
  Log.logBeginTaskScope( "getting upcArr.", this.URI );
  try
  {
    if (upcArr === undefined) 
    {
      throw new Error("Mandatory array of UPCs is undefined.");
    }
  }
  catch (e)
  {
    Log.logErrorScope( "upcArr is null.", this.URI, e );
  }
  Log.logCompletedTaskScope( "getting upcArr.", this.URI );
  this.upcArr = upcArr;
  /* -- End get UPC array -- */

  this.upc = null
  this.onhand = null;
  this.price = null;
  this.replenishable = null;
  this.name = null; /* not loaded until getName() called */
  this.taxflags = null; /* not loaded until getTaxFlags() called */
  this.timeout = false;
  if (this.useSmart) 
  {
    /* call SMART to initialize properties */
    this.init();
  }
}
InStoreItem.prototype.CLASS_NAME = "InStoreItem";
InStoreItem.prototype.URI = "/htdocs/include/ds/js/external/InStoreItem.js";

function ISIinit () 
{
  /* call smart to populate the InStoreItem properties */
  var _xmlDoc = this.smart.getInStoreItem(this.upcArr);
  var _lastValidPrice = "0.00"; //assign a default value
  var _lastUpc;
  var _lastOnhand;
  var _lastReplenishable;
  this.inItemFile = false;  // default value assumes that item not in item file

  if (_xmlDoc.documentElement) /* xml loaded successfully */
  { 
    var _cost = _xmlDoc.documentElement.getElementsByTagName("cost");
    for (var i=0; i < _cost.length; i++ )
    {
      if ( InStoreItem.isValidPrice( _cost[i].text ) )
      { 
        this.inItemFile = true;  // if we have a valid price then we know item is in file
        var _onhand = _xmlDoc.documentElement.getElementsByTagName("onhand");
        var _replenishable = _xmlDoc.documentElement.getElementsByTagName("replenishable");

        /* these vars are used if the following "if" block doesn't execute */  
        _lastValidPrice = _cost[i].text;
        _lastUpc = this.upcArr[i];
        _lastOnhand = _onhand[i].text;
        _lastReplenishable = _replenishable[i].text;

        if ( InStoreItem.isOnhand( _onhand[i].text ) || InStoreItem.isReplenishable( _replenishable[i].text ) )
        {
          /* valid item, so let's assign properties */
          this.upc = this.upcArr[i];
          this.onhand = _onhand[i].text;
          this.price = _cost[i].text;
          this.replenishable = _replenishable[i].text;
          return;
        }
      }
    }
  } else {
    /* xml did not load successfully */
    this.setIsTimeout( true );
  }

  if (this.price == null) 
  {
    /***
     * This block only executes if we don't find a valid
     *  item.
     *  
     *  Item is not sold in store, so let's set the 
     *  object properties from the last upc queried 
     **/
    this.price = _lastValidPrice;
    this.upc = _lastUpc;
    this.onhand = _lastOnhand;
    this.replenishable = _lastReplenishable;
  }
}
InStoreItem.prototype.init = ISIinit;

function ISIgetInItemFile()
{
  return this.inItemFile;
}
InStoreItem.prototype.getInItemFile = ISIgetInItemFile;

function ISIgetUpc() 
{
  return this.upc;
}
InStoreItem.prototype.getUpc = ISIgetUpc;

function ISIgetOnhand() 
{
  return this.onhand;
}
InStoreItem.prototype.getOnhand = ISIgetOnhand;

function ISIgetPrice() 
{
  return this.price;
}
InStoreItem.prototype.getPrice = ISIgetPrice;

function ISIgetName() 
{
  if (this.name == null) {
    /* lazy load this property since it's only required by the item scan gsp */
    var _itemNameXml = this.smart.getInStoreItemsPriceAndName(this.upc);
    if (_itemNameXml.documentElement)
    {
      if (_itemNameXml.documentElement.getElementsByTagName("desc")[0] != null) {
        var _name = _itemNameXml.documentElement.getElementsByTagName("desc")[0];
        this.name = _name.text;
      } else {
        return "n/a";
      }
    }
  }
  return this.name;
}
InStoreItem.prototype.getName = ISIgetName;

function ISIgetReplenishable() 
{
  return this.replenishable;
}
InStoreItem.prototype.getReplenishable = ISIgetReplenishable;

function ISIgetTaxFlags() 
{
  if (this.taxflags == null) {
    /* lazy load this property since it's only required by the POS */
    var _taxFlagXml = this.smart.getTaxFlags(this.upc);
    if (_taxFlagXml.documentElement)
    {
      var _taxFlags = _taxFlagXml.documentElement.getElementsByTagName("taxflags")[0];
      this.taxflags = _taxFlags.text;
    }
  }
  return this.taxflags;
}
InStoreItem.prototype.getTaxFlags = ISIgetTaxFlags;

/***
 * Due to onhand no being accurate, we only care
 * about (onhand > 0 || replenishable == Y) to 
 * determine if the store sells this item.
 *
 * A phone is not sold in the store or is out of stock if it does not
 * match the conditions below. For wireless we don't show the item
 * unless this condition is true.
 **/
function ISIisSoldInStore() {
  return ( InStoreItem.isValidPrice(this.price) && ( InStoreItem.isOnhand(this.onhand) || InStoreItem.isReplenishable(this.replenishable) ) );
}
InStoreItem.prototype.isSoldInStore = ISIisSoldInStore;

/***
 * CLASS METHODS
 **/
function ISIisOnhand(onhand) 
{
  return (parseInt(onhand) > 0);
}
InStoreItem.isOnhand = ISIisOnhand;

function ISIisReplenishable(replen) 
{
  if (replen == undefined) {
    return false;
  }
  return (replen.toUpperCase() == "Y");
}
InStoreItem.isReplenishable = ISIisReplenishable;

function ISIisValidPrice(price)
{
  return price!=null && price != "N/A" && parseFloat(price) != NaN;
}
InStoreItem.isValidPrice = ISIisValidPrice;

/***
 * A phone is not sold in the store or is out of stock if it does not
 * match the conditions below. For wireless we don't show the item
 * unless this condition is true.
 **/
function ISIisItemDisplayable(inStoreItem) 
{
  return ( inStoreItem != null &&
           inStoreItem.isValidPrice( inStoreItem.price ) &&
           ( inStoreItem.replenishable == true || inStoreItem.onhand > 0 )
         );
}
InStoreItem.isItemDisplayable = ISIisItemDisplayable;

function ISIgetClassName() {
  return this.CLASS_NAME;
}
InStoreItem.prototype.getClassName = ISIgetClassName;

function ISItoString() {
  var _out = this.getClassName() + " = { \n";
  _out += "this.smart = " + this.smart.toString() + ", \n";
  _out += "this.upcArr = " + this.upcArr + ", \n";
  _out += "this.upc = " + this.getUpc() + ", \n";
  _out += "this.inItemFile = " + this.getInItemFile() + ", \n";
  _out += "this.onhand = " + this.getOnhand() + ", \n";
  _out += "this.price = " + this.getPrice() + ", \n";
  _out += "this.replenishable = " + this.getReplenishable() + ", \n";
  _out += "this.name = " + this.name + ", \n"; /* don't want to call the get method b/c it lazy loads the value */
  _out += "this.taxflags = " + this.taxflags + "\n"; /* don't want to call the get method b/c it lazy loads the value */
  _out += " }";
  return _out;
}
InStoreItem.prototype.toString = ISItoString;

function ISIsetIsTimeout(timeout) {
  this.timeout = timeout;
}
InStoreItem.prototype.setIsTimeout = ISIsetIsTimeout;

function ISIgetIsTimeout() {
  return this.timeout;
}
InStoreItem.prototype.getIsTimeout = ISIgetIsTimeout;
