// This file uses JSDoc-friendly comments [ http://jsdoc.sourceforge.net/ ]

/**
 * @file         aimitems.js
 * @fileoverview Collection of application level classes.<br/>
 * This collection implements the rich-internet-application tier of
 * the Inventory Module for AIM (Auction Inventory Management),
 * which is a demonstration of the Gravey framework.
 * @author       Bruce Wallace  (PolyGlotInc.com)
 * @requires     grvEDO.js
 * @requires     grvAJAX.js
 * @version      2.0
 */

////////////////////////////////////////////
//////////// Domain Objects ////////////////
////////////////////////////////////////////


Class(LotDecode,["Lot Key","Lot Name","Lot Number"])
.Extends(MVCDecode);
/**
 * @class This class encapsulates a Lot picklist item.
 * @extends MVCDecode
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function LotDecode()
{
	/** @param {int} lotkey unique key of this lot
	 *  @param {String} lotname lot name
	 *  @param {int} lotnum lot number
	 */
	this.konstructor = function( lotkey, lotname, lotnum ) {
		this.souper( "Lot", lotkey, lotname, lotnum  );
	}

	/** return the description of "this" @type String */	
	this.getDescription = function() {
		return "Lot# "+this.aux+"  "+this.desc;
	}
}

Class(ItemSummary,["unique Key","Item Name","Item Type Code",
					"Lot Number","Pulled Flag","Item Number"])
.Extends(EDOHolderSelectionItem);
/**
 * @class This class encapsulates the identifying attributes of an auction Item.
 * @extends EDOHolderSelectionItem
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ItemSummary()
{
	/** @param {int} theKey unique key of this record
	 *  @param {String} iName item's name
	 *  @param {String} iType item type code
	 *  @param {int} lNum lot number
	 *  @param {boolean} pulled item pulled flag
	 *  @param {int} iNum item number
	 */
	this.konstructor = function( theKey, iName, iType, lNum, pulled, iNum )
	{
		// define instance variables
		this.key	= theKey;
		this.iName	= iName;
		this.iType	= iType;
		this.lotNo  = lNum;
		this.pulled = pulled;
		this.iNum   = iNum;
	}

	/** return "this" formatted for main menu item @type String */
	this.getDescription = function()
	{
		var		s = new Array();
				s.push( grvDiamond(!this.pulled)+this.lotNo );
				s.push( this.iNum  );
				s.push( this.iName );
		return	s.join( "-" );
	}

	/** return "this" as human-readable string @type String */
	this.toString = function()
	{
		var		s = new Array();
				s.push( this.key );
				s.push( this.iName );
				s.push( this.lotNo );
				s.push( this.iNum );
		return	s.join( "-" );
	}

	/** set this to given values
	 * @param {ItemSummary} it exemplar to emulate
	 */
	this.updateProperties = function( it ){
		this.key	= it.key;
		this.iName	= it.iName;
		this.iType	= it.iType;
		this.lotNo  = it.lotNo;
		this.pulled = it.pulled;
		this.iNum   = it.iNum;
	}
}


Class(PLIndex).Extends(EDOIndex);
/**
 * @class This class encapsulates an EDO index for Plain/Loan.
 * @extends EDOIndex
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function PLIndex()
{
  if (!PLIndex.Plain){//keep this line above jsdoc comments!

	/** Static factory method to generate Item-flavored index @type PLIndex
	 * @param {int} index Item index
	 */
	PLIndex.Plain = function(){ return new PLIndex(0,null); }

	/** Static factory method to generate Loan-flavored index @type BSCIndex
	 * @param {int} index Loan index
	 */
	PLIndex.Loan  = function(){ return new PLIndex(0,0);	}

	/** synonym for PLIndex.Plain @type PLIndex */
	PLIndex.Item  = function(){ return PLIndex.Plain();     }
  }

	/** @param {int} optP index into Item list for current Auction
	 *  @param {int} optL index into Loan list for specified Item
	 * If args not specified or if all are null then this represents "no selection".
	 */
	this.konstructor = function( optP,optL )
	{
		// define instance variables
		this.p = optP===undefined ? null : optP;
		this.l = optL===undefined ? null : optL;
	}

	/** return "this" as event handler arg list string @type String */	
	this.asEventArgs = function() {
		return " new PLIndex("+this.p+","+this.l+") ";
	}

	this.asString = function() {
		return this.invoke( this, this._noString, this._lonString )
		     + this._itString( this.p );
	}

	this._noString = function(){ return ""; }

	/** return item/property description @type String */
	this._itString = function( pindex ){ 
		var a = gItemData._getItem( pindex );
		if (a && a[ kStrIdName ]) return a[ kStrIdName ];
		return (a && !a.isNew()) ? "Unnamed Item" : "New Item";
	}
	/** return loan description @type String */
	this._lonString = function( cindex ){
		cindex -= 0; //type cast to int
		return "Loan Attributes of ";
	}


	/** return whether "this" contains a selection @type boolean */
	this.hasSelection = function(){ return this.p!=null
	                                    || this.l!=null; }
	
	/** return whether "this" equals given EDOIndex @type boolean */
	this.equals = function(x){
		return x ? (this.p==x.p && this.l==x.l) : false;
	}

	/** Invoke the appropriate method given the index type and
	 * return its result. Methods are expected to have the signature<pre>
	 * self.method(this.subindex,optionalArgument)
	 *</pre>
	 * @param {Object} self the parent object of the method
	 * @param {Function} pMethod method to call if xi is Plain type
	 * @param {Function} lMethod method to call if xi is Loan  type
	 * @param {Object} optArg optional extra param to pass to method
	 * @return the result of the called method
	 */
	this.invoke = function(self,pMethod,lMethod,optArg){
		var aMethod;
		var i;
		if (this.l!=null) { aMethod = lMethod; i = this.l; } else
                          { aMethod = pMethod; i = this.p; }
		return aMethod.call( self, i, optArg );
	}

}

///////////////////////////////////////////////////////////////////////
// Constants defining property names for the Plain/loan properties
///////////////////////////////////////////////////////////////////////

// Plain attributes...
var kIntIdLotNum     = 'Lot#';				//based on Lot Key
var kIntIdLotKey     = 'Lot';				//cant be null
var kBoolIdPulled    = 'Pulled?';			//cant be null
var kBoolIdEligVIP   = 'VIP Eligible?';		//cant be null
var kStrIdItemType   = 'Item Category';		//cant be null
var kDateIdLast      = 'Last Updated';		//cant be null
var kDateIdFirst     = 'First Added';		//cant be null
var kStrIdName       = 'Item Name';
var kAddrIdStreet    = 'Street';
var kAddrIdState     = 'State';
var kAddrIdCity      = 'City';
var kAddrIdZip       = 'Zip';
var kAmtIdBook       = 'Retail Value';
var kPctIdTarget     = 'Target%';
var kPctIdReserve    = 'Reserve%';
var kIntIdItemNum    = 'Item#';
var kStrIdComments2  = 'Description';
var kStrIdOwnName    = 'Owner Name';

//Loan attributes...
var kStrIdBank       = 'Bank #';			//cant be null
var kPctIdIntRate    = 'Interest Rate';

Class(PLEDO,["parent holder model", "edo Class", "property values array",
			 "edit Date","edit User","unique Key" ])
.Extends(EDO);
/**
 * @class This is the abstract base class for PlainItems/LoanItems EDOs.
 * @extends EDO
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function PLEDO()
{
	/** 
	 *  @param {ItemModel} holder parent EDOHolderModel
	 *  @param {Function} CLAZZ this EDO's "class"
	 *  @param {array}  propValues array of property initial values
	 *  @param {String} editDate date of last edit
	 *  @param {String} editUser ID of last user to edit
	 *  @param {int} theKey unique key of this record
	 *  @param {int} optEditStatus optional edit status where the
	 * status codes are: 0=no-change; 1=delete; 2=create; 3=hidden; 4=update
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	(
		holder,
		CLAZZ,
		propValues,
		editDate,
		editUser,
		theKey,
		optEditStatus,
		optName
	){
		this.souper( CLAZZ, holder, propValues, editDate, editUser,
					theKey, optEditStatus, optName );
	}

	/** push into given array all PLEDO-specific fields of the UpdateItem message
	 * formatted as<pre>
	 * "{isLoanFlag}~{property1}~...~{propertyN}"
	 * where the fields are defined as follows...
	 *     {isLoanFlag} = "Y" iff parent EDOHolder contains a Loan
	 *     {propertyI}  = the i-th editable property of this EDO
	 *</pre>
	 * @param {Array} uFields  string array containing Update Msg fields
	 */
	this.pushUpdateFields = function( uFields )
	{
		uFields.push( this.holder.isLoan()?'Y':'N' );
		this.pushEncodedValues( uFields );
	}
}

Class(Item,["property values array","edit Date","edit User",
			 "unique Key","parent holder"])
.Extends(PLEDO);
/**
 * @class This class encapsulates an Auction Item record.
 * @extends PLEDO
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function Item()
{
	// init "static" Class methods/elements
	if (!Item.Properties) {//keep this line above jsdoc comments!

		/** Static factory method to generate blank Item @type Item */
		Item.Factory = function(index,holder)
		{
			var x = new Item( null, grvGetTodayAsMMDDYYYY(),kUserID,null,holder );

			x[ kAmtIdBook     ] = 0;
			x[ kPctIdTarget   ] = 0;
			x[ kPctIdReserve  ] = 0;
			x[ kIntIdLotNum   ] = kLotKey ? kLotNumber : 0;
			x[ kIntIdLotKey   ] = kLotKey ? kLotKey    : kLotZeroKey;
			x[ kDateIdFirst   ] = x.date;
			x[ kDateIdLast    ] = x.date;
			x[ kBoolIdPulled  ] = false;
			x[ kBoolIdEligVIP ] = false;
			x[ kStrIdItemType ] = "AI";

			return x;
		}

		// init static member variables
		Item.UpdateID   = "Item";
		Item.Properties = [  kIntIdLotKey,
				kIntIdLotNum, kBoolIdPulled, kBoolIdEligVIP, kStrIdItemType,
				kDateIdLast, kDateIdFirst, kStrIdName, kAddrIdStreet,
				kAddrIdCity, kAddrIdState, kAddrIdZip, kAmtIdBook,
				kPctIdTarget, kPctIdReserve, kIntIdItemNum,
				kStrIdComments2, kStrIdOwnName
		];

		Item.EditRules  = [ MVCEditRule.kPOS, 
				MVCEditRule.kRO, MVCEditRule.kBOOL, MVCEditRule.kBOOL, MVCEditRule.kALFA,
				MVCEditRule.kDATE, MVCEditRule.kDATE, MVCEditRule.kEdit, MVCEditRule.kEdit,
				MVCEditRule.kAlfa, MVCEditRule.kAlfa, MVCEditRule.kZip, MVCEditRule.kDec,
				MVCEditRule.kDec, MVCEditRule.kDec, MVCEditRule.kInt,
				MVCEditRule.kEdit, MVCEditRule.kEdit
		];
	}

	/** @param {array} array of editable property values in same order as .Properties
	 *  @param {String} editDate date of last edit
	 *  @param {String} editUser ID of last user to edit
	 *  @param {int} theKey unique key of this record
	 *  @param {ItemModel} holder parent EDOHolderModel
	 *  @param {int} optEditStatus optional edit status
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	( propArray, editDate, editUser, theKey, holder, optEditStatus, optName )
	{
		this.souper( holder, Item,
		 propArray, editDate, editUser,	theKey, optEditStatus, optName );
		
		this[ kIntIdItemNum+MVCAttributeModel.kValidateSuffix ] = this.validateItemNum;
	}

	/** custom validation method to verify uniqueness of Item number
	 * @type String
	 * @return error message or null if no error
	 */
	this.validateItemNum = function()
	{
		if ( grvIsEmpty(this[kIntIdItemNum]) ) return null;
		if ( this[kIntIdItemNum]==0 ) return "Item number zero is not allowed.";
		if ( this.hasDuplicateItemNum()) return "Duplicate Item numbers are not allowed.";
		return null;
	}

	/** custom validation method to verify uniqueness of Item number
	 * @type boolean
	 * @return true iff our item number duplicates any in parent lot
	 */
	this.hasDuplicateItemNum = function() {
		return this.holder.itemCount( this[kIntIdItemNum], this.key ) > 1;
	}

	/** return a clone of this object @type Item */
	this.clone = function() {
		return new Item( this.propValues(), this.date, this.whom,
			this.key, this.holder, this.editStatus );
	}

	this.toString = function() {
		var s = grvIsEmpty(this[kIntIdItemNum]) ? "" : ("#"+this[kIntIdItemNum]);
		var t = grvIsEmpty(this[kStrIdName   ]) ? "" : (" "+this[kStrIdName   ]);
		return s+t;
	}

	this.canCreate = function(appendFlag) {
	  return this.holder.isTrue()
		 ? "Can't add a new Item until pending changes have been saved"
		 : null;
	}

	this.canDelete = function(){
		if ( this.isActive() && !kLaunched  ) return null;
		return 'Items can not be deleted after Auction Launch. Mark as "pulled" instead.';
	}

	/** If created, can we undo creation? @type boolean
	 * @param {boolean} appendFlag if true then append else insert
	 */
	this.canUncreate = function(appendFlag){ return false; }//override me
}

////////////////////////////////////////////////////////////////////////////////

Class(Loan,["property values array","edit Date","edit User",
			"unique Key","parent holder"])
.Extends(PLEDO);
/**
 * @class This class encapsulates any optional financing available
 * for an Item (i.e. the "loan" record).
 * @extends PLEDO
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function Loan()
{
	// init "static" Class methods/elements
	if (!Loan.Properties) {//keep this line above jsdoc comments!

		/** Static factory method to generate blank Loan @type Loan */
		Loan.Factory = function(index,holder)
		{
			var x = new Loan( null,grvGetTodayAsMMDDYYYY(),kUserID,null,holder );
			x[ kStrIdBank    ] = "000";
			x[ kPctIdIntRate ] = 0;
			return x;
		}

		// init static member variables
		Loan.Title      = "Financing Available";
		Loan.UpdateID   = "Loan";
		Loan.Properties = [ kStrIdBank, kPctIdIntRate ];
		Loan.EditRules  = [ MVCEditRule.kALNO, MVCEditRule.kDec ];
	}

	/** @param {array} array of editable property values in same order as .Properties
	 *  @param {String} editDate date of last edit
	 *  @param {String} editUser ID of last user to edit
	 *  @param {int} theKey unique key of this record
	 *  @param {ItemModel} holder parent EDOHolderModel
	 *  @param {int} optEditStatus optional edit status
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	( propArray, editDate, editUser, theKey, holder, optEditStatus, optName )
	{
		this.souper( holder, Loan,
		 propArray, editDate, editUser, theKey, optEditStatus, optName );
	}

	/** return a clone of this object @type Loan */
	this.clone = function() {
		return new Loan( this.propValues(), this.date, this.whom,
			this.key, this.holder, this.editStatus );
	}

	this.toString = function()
	{
		return this[ kStrIdBank ];
	}

	this.canCreate = function(appendFlag) {
		return "There can only be one set of Loan Attributes.";
	}

	this.canDelete = function(){
		if ( this.isNew() && this.isActive() ) return null;
		return "This section can't be deleted. The entire Item must be deleted.";
	}
}

////////////////////////////////////////////
////////////// Data Models /////////////////
////////////////////////////////////////////

Class(ItemModel,["Item Selection Model"]).Extends(EDOHolderModel);
/**
 * @class This class encapsulates the data model of a particular Item.
 * This model subscribes to a {@link ItemSelectionModel}
 * so that it can be downloaded whenever a new Item is selected.
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ItemModel()
{
	/** @param {ItemSelectionModel} itemSelectionModel model of which Item is selected
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function( itemSelectionModel, optName )
	{
		// init static DOM (must do this here instead of above!)
		if (!ItemModel.LoadXslDOM) ItemModel.LoadXslDOM = grvGetXslDOM( kXSLPath+"AIMitToJS.xsl" );
		var holderName = optName ? optName : "Item";
		this.souper( itemSelectionModel, ItemModel.LoadXslDOM, holderName );

		// init instance variables
		this._resetEDOs();
	}

	/** return the parent item name for this model @type String */
	this.getName = function(){
		return this.item ? this.item[kStrIdName] : null;
	}

	/** return the parent item lot number for this model @type String */
	this.getLotNo = function(){
		return this.item ? kLotMap.getItem( this.item[kIntIdLotKey] ).aux : null;
	}

	/** return whether any EDOs are changed for this model @type boolean */
	this.isDirty = function()
	{
		if (this.item && this.item.inEdit()) return true;
		if (this.loan && this.loan.inEdit()) return true;
		return false;
	}

	/** return whether all EDOs are valid for this model @type boolean */
	this.isValid = function()
	{
		if (!this.item    || !this.item.isValid()) return false;

		//special case: if we are deleting item then loan errs dont matter
		if (this.item.isDeleted()) return true;

		if (this.isLoan() && !this.loan.isValid()) return false;
		return true;
	}

	/** clear EDOs */
	this._resetEDOs = function( optItem, optLoan )
	{
		this.item  = optItem ? optItem : null;
		this.loan  = optLoan ? optLoan : null;
	}
	
	this.isLoan = function(){ return this.loan!=null; }

	/** set our Plain object but dont publish */
	this._setItem = function(o){ this.item = o; }
	/** set our Loan  object but dont publish */
	this._setLoan = function(o){ this.loan = o; }

	/** return the debug details of "this" @type String */
	this.dump = function()
	{
		var		dStr = new Array();
				dStr.push( "ItemModel>>>[" );
				dStr.push( "item="+(this.item?this.item.dump():"null") );
				dStr.push( "loan="+(this.loan?this.loan.dump():"null") );
				dStr.push( "]" );
		return	dStr.join("\n");
	}

	/** create a new item for the selection list from current EDO
	 * @type EDOHolderSelectionItem
	 */
	this.createSelectionItem = function()
	{
		return new ItemSummary(
			this.item.key,
		    this.getName(),
		    this.item[kStrIdItemType],
		    this.getLotNo(),
		    this.item[kBoolIdPulled],
		    this.item[kIntIdItemNum]
		);
	}

	/** return the updated properties from the current EDO needed for select list update
	 * @return arbitrary value as needed @type Object
	 */
	this.getUpdatedProperty = function(){ return this.createSelectionItem(); }

	/** return whether there is currently an EDO @type boolean */
	this.hasEDO = function(){ return this.item!=null; }

	/** return whether current EDO matches selection item "key"
	 * @type boolean
	 * @param {EDOHolderSelectionItem} item selection menu item
	 */
	this.keysMatch = function(item){ return this.item.key==item.key; }

	/** return whether current EDO matches selection item "properties"
	 * @type boolean
	 * @param {EDOHolderSelectionItem} item selection menu item
	 */
	this.propMatch = function(item){
		return item.iName ==this.getName()
		    && item.pulled==this.item[kBoolIdPulled]
		    && item.lotNo ==this.getLotNo()
		    && item.aNum  ==this.item[kIntIdItemNum];
	}

	/** push into given array all AJAX SAVE Post params for this model
	 * @param {Array} posts  string array containing POST params
	 */
	this.pushPosts = function( posts )
	{
		this.item.pushPosts( posts );	//THIS **MUST** BE FIRST!!
		if (this.isLoan())
		this.loan.pushPosts( posts );
	}

	/** return a new blank EDO of the type implied by EDOIndex @type EDO
	 * @param {EDOIndex} xi edo index
	 */
	this._newEDO = function(xi) { 
		return xi.invoke( this, Item.Factory, Loan.Factory, this );
	}

	/** return the specified item @type Item
	 * @param {int} i index into item list
	 */
	this._getItem = function( i ) {
	  return (i==0 && this.item) ? this.item : null;
	}
	/** return the specified loan @type Loan
	 * @param {int} i index into loan list
	 */
	this._getLoan = function( i ) {
	  return (i==0 && this.loan) ? this.loan : null;
	}
	/** return reference to the specified editable domain object
	 * @param {PLIndex} xi edo index
	 */
	this.getEDO  = function(xi){
		return xi.invoke( this, this._getItem, this._getLoan );
	}

	/** create new EDO which is inserted after selected EDO
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {EDOIndex} xi edo index
	 */
	this.createEDO = function(xi){
		xi.invoke( this, this._newItem, this._newLoan, this.newEDO(xi) );
		return xi;
	}

	/** create a new item
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {int} i item list index
	 * @param {EDO} edo the item
	 */
	this._newItem = function( i, itemEDO )
	{
		//auto-create loan section
		var loanEDO = this.newEDO( PLIndex.Loan() );
		this._resetEDOs( itemEDO, loanEDO );
		this.updateStamp();
		return PLIndex.Plain();
	}

	/** create a new loan
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {int} i loan list index
	 * @param {EDO} edo the loan
	 */
	this._newLoan = function( i, edo ) {
		this.updateStamp();
		return PLIndex.Loan();
	}
	/** create new EDO which is appended at end of EDO list
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {EDOIndex} xi edo index
	 */
	this.appendEDO = function(xi){
		return xi.invoke( this, this._newItem, this._newLoan, this.newEDO(xi) );
	}

	/** toggle the "expanded" flag of the specified EDOs.
	 * @param {boolean} doAllFlag if true, set all of the EDOs to new value
	 * @param {EDOIndex} xi edo index
	 */
	this.toggleExpand = function( doAllFlag, xi )
	{
		var edo = this.getEDO(xi);
		if (doAllFlag)
		{
			var newVal = !edo.isExpanded();
			this.item.toggleExpand( newVal );
			this.loan.toggleExpand( newVal );
		}
		else edo.toggleExpand();
		this.updateStamp();
	}

	/** return how many item have the given item number in its lot @type int */
	this.itemCount = function( itemnum, key )
	{
		var lotnum = this.getLotNo();
		if (lotnum==null || itemnum==null) return 0;

		var count = 1;
		this.model.model.iterate( function(i,it){
			if (it.key!=key && it.lotNo==lotnum && it.iNum==itemnum && !it.pulled) ++count;
		} );
		return count;
	}
}


Class(ItemSelectionModel,["ItemSummary List Model"]).Extends(EDOHolderSelectionModel);
/**
 * @class This class encapsulates the data model for
 * "which Item is currently selected".
 * @extends EDOHolderSelectionModel
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ItemSelectionModel()
{
	/** @param {ListModel} listModel {@link ItemSummary} list */
	this.konstructor = function( listModel ){
		this.souper( listModel, "Item " );
	}

	/** Return the list index of the specified Item or <0 if not found. @type int */
 	this.findItem = function( itemKey )
	{
		var list = this.model;
		var N    = list.getCount();
		if (N<1) return -2;//NO DATA IN item SUMMARY LIST!!

		for (var i=0; i<N; ++i)
		  if (list.getItem(i).key == itemKey) return i;

		return -1;
	}

	/** Select the "initially selected" EDOHolder<br>
	 * @param {boolean} selectFirst if selection critera has no match then
	 * if selectFirst==true then select the first in list
	 *                      else leave selection alone 
	 */
 	this.selectInitial = function( selectFirst )
	{
		var i = this.findItem( kItemKey );
		if (i==-2){ this.selectNothing(); return; }//EMPTY LIST!!
		if (i>= 0){ this.select(i);       return; }//found it
		if (selectFirst) this.select(0);
	}
}

////////////////////////////////////////////
////////////// Controllers /////////////////
////////////////////////////////////////////


////////////////////////////////////////////
////////////// Data Views  /////////////////
////////////////////////////////////////////


Class(ItemView,["Item object"])
.Extends(EDOView);
/**
 * @class This class produces a view of a {@link Item}.
 * @extends EDOView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ItemView()
{
	/** @param {Item} item Item we are to observe
	 */
	this.konstructor = function( item ) {
		this.souper( item, PLIndex.Plain() );
	}

	this.preSelect = function() {
		this.sharedMenuSelect(   gLotSelected, kIntIdLotKey );
		this.sharedMenuSelect( gITypeSelected, kStrIdItemType );
	}

	this.buildFields = function( HTML )
	{
		HTML.push( this.buildStrField( kStrIdName     , 50, 50, false, 3 ) );
		HTML.push( this.buildPopField( kIntIdLotKey   ,         false, gLotSelected, 2 ) );
//		HTML.push( this.buildStrField( kIntIdLotKey   , 10, 10, false ) );
//		HTML.push( this.buildStrField( kIntIdLotNum   ,  3,  3, false ) );
		HTML.push( this.buildStrField( kIntIdItemNum  ,  3,  3, false ) );
		HTML.push( this.buildBoxField( kBoolIdPulled  ,         true  ) );

		HTML.push( this.buildStrField( kStrIdOwnName  , 50, 50, false, 3 ) );
		HTML.push( this.buildDayField( kDateIdFirst   ,         false ) );
		HTML.push( this.buildDayField( kDateIdLast    ,         false ) );
//		HTML.push( this.buildUprField( kStrIdItemType ,  2,  2, false ) );
		HTML.push( this.buildPopField( kStrIdItemType ,         false, gITypeSelected ) );
		HTML.push( this.buildBoxField( kBoolIdEligVIP ,         true  ) );

		HTML.push( this.buildTxtField( kAddrIdStreet,2, 50,250, false, 3 ) );
//		HTML.push( this.buildTxtField( kAddrIdStreet  , 50,250, false, 3 ) );
		HTML.push( this.buildPctField( kPctIdTarget   ,         false ) );
		HTML.push( this.buildPctField( kPctIdReserve  ,         false ) );
		HTML.push( this.buildAmtField( kAmtIdBook     ,         true  ) );

		HTML.push( this.buildStrField( kAddrIdCity    , 20, 50, false ) );
		HTML.push( this.buildUprField( kAddrIdState   ,  2,  2, false ) );
		HTML.push( this.buildStrField( kAddrIdZip     , 10, 10, true  ) );

		HTML.push( this.buildTxtField( kStrIdComments2,4,120,2000,true, 7 ) );
	}
}

Class(LoanView,["Loan object"])
.Extends(EDOView);
/**
 * @class This class produces a view of a {@link Loan}.
 * @extends EDOView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function LoanView()
{
	/** @param {Loan} loan Loan we are to observe
	 */
	this.konstructor = function( loan ) {
		this.souper( loan, PLIndex.Loan() );
	}

	this.buildFields = function( HTML )
	{
		HTML.push( this.buildStrField( kStrIdBank   ,  3,  3, false ) );
		HTML.push( this.buildPctField( kPctIdIntRate,         false ) );
	}
}


Class(ItemModelView,["Item data model"])
.Extends(EDOHolderView);
/**
 * @class This class produces the view of the entire data panel.
 * @extends EDOHolderView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ItemModelView()
{
	/** @param {ItemModel} itModel Item/Loan we are to observe */
	this.konstructor = function( itModel ) {
		this.souper( itModel );
	}

	this.buildFields = function( HTML )
	{
	  var vwID      = this.getWidgetID();
	  var selected  = this.model;

	  if ( !selected.item || selected.item.inLimbo() )
	  {
		if (!grvWAITING())
		HTML.push( EDOView.ShellHTML( PLIndex.Item(), Item ) );
	  }
	  else if ( selected.item.isActive() )
      {
		HTML.push( this.embedHTML( vwID+".itWdgt",
						new ItemView( selected.item ) ) );

		if ( selected.isLoan() || selected.item.isNew() )
		  if ( !selected.loan || selected.loan.inLimbo() )
		  {
			if (!grvWAITING())
			HTML.push( EDOView.ShellHTML( PLIndex.Loan(), Loan ) );
		  }
		  else if ( selected.loan.isViewable() )
			HTML.push( this.embedHTML( vwID+".loWdgt",
		                new LoanView( selected.loan ) ) );
      }
      else HTML.push( '<thead>This Item is deleted. You must Cancel, Save, or Undo.</thead>' );
	}
}

