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

/**
 * @file         aimbidders.js
 * @fileoverview Collection of application level classes.<br/>
 * This collection implements the rich-internet-application tier of
 * the Bidders 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(BidderSummary,["unique Key","Company Name","FICO Code","lot count","inactive flag"])
.Extends(EDOHolderSelectionItem);
/**
 * @class This class encapsulates the identifying attributes of an Auction Bidder.
 * @extends EDOHolderSelectionItem
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function BidderSummary()
{
	/** @param {int} theKey primary key of this record
	 *  @param {String} coName Bidder's company name
	 *  @param {String} fico Bidder's FICO code
	 *  @param {int} lotCount count of lots attached to this Bidder
	 *  @param {boolean} inactive no-longer-active flag
	 */
	this.konstructor = function( theKey, coName, fico, lotCount, inactive )
	{
		// define instance variables
		this.key	= theKey;
		this.coName	= coName;
		this.fico	= fico;
		this.count  = lotCount;
		this.dead   = inactive;
	}

	/** return "this" formatted for main menu item @type String */
	this.getDescription = function() {
		return grvDiamond(!this.dead)+this.coName;
	}

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

	/** set name to given value */
	this.updateProperties = function( bsum ){
		this.key	= bsum.key;
		this.coName	= bsum.coName;
		this.fico	= bsum.fico;
		this.count  = bsum.count;
		this.dead   = bsum.dead;
	}
}


Class(BSCIndex).Extends(EDOIndex);
/**
 * @class This class encapsulates an EDO index for Bidder/Shipping/Contact.
 * @extends EDOIndex
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function BSCIndex()
{
  if (!BSCIndex.Bidder){//keep this line above jsdoc comments!
	/** Static factory method to generate Bidder-flavored index
	 * @param {int} index Bidder index
	 * @type BSCIndex
	 */
	BSCIndex.Bidder = function() {
		return new BSCIndex(0,null,null);
	}
	/** Static factory method to generate Shipping-flavored index
	 * @param {int} index Shipping index
	 * @type BSCIndex
	 */
	BSCIndex.Shipping = function( index ) {
		return new BSCIndex(0,index,null);
	}
	/** Static factory method to generate Contact-flavored index
	 * @param {int} index Contact index
	 * @type BSCIndex
	 */
	BSCIndex.Contact = function( index ) {
		return new BSCIndex(0,null,index);
	}
  }

	/** @param {int} optB index into Bidders  list for current Auction
	 *  @param {int} optS index into Shipping list for specified Bidder
	 *  @param {int} optC index into contacts list for specified Bidder
	 * If args not specified or if all are null then this represents "no selection".
	 */
	this.konstructor = function( optB,optS,optC )
	{
		// define instance variables
		this.b = optB===undefined ? null : optB;
		this.s = optS===undefined ? null : optS;
		this.c = optC===undefined ? null : optC;
	}

	/** return "this" as event handler arg list string @type String */	
	this.asEventArgs = function() {
		return " new BSCIndex("+this.b+","+this.s+","+this.c+") ";
	}

	this.asString = function() {
		return this.invoke( this, this._noString, this._shpString, this._conString )
		     + this._bidString( this.b );
	}

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

	/** return Bidder description @type String */
	this._bidString = function( bindex ){ 
		var b = gBidderData._getBidder( bindex );
		return (b && b[ kStrIdCompany ]) ? b[ kStrIdCompany ] : "New Bidder";
	}
	/** return contact description @type String */
	this._conString = function( cindex ){
		cindex -= 0; //type cast to int
		return "Contact["+(cindex+1)+"] of ";
	}
	/** return Shipping description @type String */
	this._shpString = function( sindex ){
		sindex -= 0; //type cast to int
		return "Shipping["+(sindex+1)+"] of ";
	}

	/** return whether "this" contains a selection @type boolean */
	this.hasSelection = function(){ return this.b!=null
	                                    || this.s!=null
	                                    || this.c!=null; }
	
	/** return whether "this" equals given EDOIndex @type boolean */
	this.equals = function(x){
		return x ? (this.b==x.b && this.s==x.s && this.c==x.c) : 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} bMethod method to call if xi is Bidder   type
	 * @param {Function} sMethod method to call if xi is Shipping type
	 * @param {Function} cMethod method to call if xi is Contact  type
	 * @param {Object} optArg optional extra param to pass to method
	 * @return the result of the called method
	 */
	this.invoke = function(self,bMethod,sMethod,cMethod,optArg){
		var aMethod;
		var i;
		if (this.s!=null) { aMethod = sMethod; i = this.s; } else
		if (this.c!=null) { aMethod = cMethod; i = this.c; } else
                          { aMethod = bMethod; i = this.b; }
		return aMethod.call( self, i, optArg );
	}

}

////////////////////////////////////////////////////////////////////////////////
// Constants defining property names for the Bidder/contact/Shipping properties
////////////////////////////////////////////////////////////////////////////////

var kStrIdCompany  = 'Company';
var kCodeIdFICO    = 'FICO';
var kBoolInactive  = 'Inactive?';
var kStrIdName     = 'Contact Person';
var kStrIdWireInst = 'Wiring Instructions';
var kAddrIdStreet  = 'Street';
var kAddrIdState   = 'State';
var kAddrIdCity    = 'City';
var kAddrIdZip     = 'Zip';
var kPhoneIdMain   = 'Phone';
var kPhoneIdFax    = 'Fax';
var kEMailIdAddr   = 'EMail Address';


Class(BSCEDO,["parent BidderModel","lot count",
	"edo Class","property values array",
	"edit Date","edit User","unique Key"])	
.Extends(EDO);
/**
 * @class This is the abstract base class for Bidder/Shipping/Contact EDOs.
 * @extends EDO
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function BSCEDO()
{
	/** 
	 *  @param {BidderModel} holder parent EDOHolderModel
	 *  @param {int} lotcount how many Lots are linked to this
	 *  @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,
		lotcount,
		CLAZZ,
		propValues,
		editDate,
		editUser,
		theKey,
		optEditStatus,
		optName
	){
		this.souper( CLAZZ, holder, propValues, editDate, editUser,
					theKey, optEditStatus, optName );

		// define instance variables
		this.lotCount = lotcount;
	}

	this.toolTip = function( xi ){
		return this.edoToolTip(xi) + " Lots="+this.lotCount;
	}

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

	this.canDelete = function()
	{
		if (!this.isActive())
		  return "This is already deleted.";

		var c = this.lotCount;
		if (c>0)
		  return "This can't be deleted. It is referenced by "
		            +c+" Lot"+(c==1?".":"s.");

		return null;
	}

	/** push into given array all BSCEDO-specific fields of the UpdateItem message
	 * formatted as<pre>
	 * "{parentBidderName}~{property1}~...~{propertyN}"
	 * where the fields are defined as follows...
	 *     {parentBidderName} = "my" parent Bidder company name
	 *     {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( encodeURIComponent(this.holder.getName()) );
		this.pushEncodedValues( uFields );
	}
}

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

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

		// init static member variables
		Bidder.UpdateID   = "Bidder";
		Bidder.Properties = [ kStrIdCompany, kCodeIdFICO, kBoolInactive ];
		Bidder.EditRules  = [ MVCEditRule.kReqd, MVCEditRule.kAlNo, MVCEditRule.kBOOL ];
	}

	/** @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 {BidderModel} holder parent EDOHolderModel
	 *  @param {int} lotcount how many Lots are linked to this
	 *  @param {int} optEditStatus optional edit status
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	( propArray, editDate, editUser, theKey, holder, lotcount, optEditStatus, optName )
	{
		this.souper( holder, lotcount, Bidder,
		 propArray, editDate, editUser,	theKey, optEditStatus, optName );
	}

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

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

	/** 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(Contact,["property values array","edit Date","edit User",
			   "unique Key","parent Bidder","lot count"])
.Extends(BSCEDO);
/**
 * @class This class encapsulates a Bidder "contact" record.
 * @extends BSCEDO
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function Contact()
{
	// init "static" Class methods/elements
	if (!Contact.Properties) {//keep this line above jsdoc comments!

		/** Static factory method to generate blank Contact @type Contact */
		Contact.Factory = function(index,holder) {
		return new Contact( null,grvGetTodayAsMMDDYYYY(),kUserID,null,holder,0 );
		}

		// init static member variables
		Contact.UpdateID   = "Contact";
		Contact.Properties = [
				kStrIdName, kPhoneIdMain, kPhoneIdFax, kAddrIdStreet,
				kAddrIdCity, kAddrIdState, kAddrIdZip, kEMailIdAddr,
				kStrIdWireInst ];
		Contact.EditRules  = [
				MVCEditRule.kEdit, MVCEditRule.kFone, MVCEditRule.kFone, MVCEditRule.kEdit,
				MVCEditRule.kAlfa, MVCEditRule.kAlfa, MVCEditRule.kZip, 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 {BidderModel} holder parent EDOHolderModel
	 *  @param {int} lotcount how many Lots are linked to this
	 *  @param {int} optEditStatus optional edit status
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	( propArray, editDate, editUser, theKey, holder, lotcount, optEditStatus, optName )
	{
		this.souper( holder, lotcount, Contact,
		 propArray, editDate, editUser, theKey, optEditStatus, optName );
	}

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

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

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

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

		/** Static factory method to generate blank Shipping @type Shipping */
		Shipping.Factory = function(index,holder) {
		return new Shipping( null,grvGetTodayAsMMDDYYYY(),kUserID,null,holder,0 );
		}

		// init static member variables
		Shipping.UpdateID   = "Shipping";
		Shipping.Properties = [
				kStrIdName, kPhoneIdMain, kPhoneIdFax, kAddrIdStreet,
				kAddrIdCity, kAddrIdState, kAddrIdZip, kEMailIdAddr,
				kStrIdCompany ];
		Shipping.EditRules  = [
				MVCEditRule.kEdit, MVCEditRule.kFone, MVCEditRule.kFone, MVCEditRule.kEdit,
				MVCEditRule.kAlfa, MVCEditRule.kAlfa, MVCEditRule.kZip, 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 {BidderModel} holder parent EDOHolderModel
	 *  @param {int} lotcount how many Lots are linked to this
	 *  @param {int} optEditStatus optional edit status
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function
	( propArray, editDate, editUser, theKey, holder, lotcount, optEditStatus, optName )
	{
		this.souper( holder, lotcount, Shipping,
		 propArray, editDate, editUser,	theKey, optEditStatus, optName );
	}

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

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

Class(BidderModel,["Bidder Selection Model"]).Extends(EDOHolderModel);
/**
 * @class This class encapsulates the data model of a particular Bidder.
 * This model subscribes to a {@link BidderSelectionModel}
 * so that new Contact and Shipping lists can be downloaded whenever
 * a new Bidder is selected.
 * <p>NOTE: Other parts of AIM assume that the Contact and Shipping
 * lists will never be null; zero items is ok though.</p>
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function BidderModel()
{
	/** @param {BidderSelectionModel} BidderSelectionModel model of which Bidder is selected
	 *  @param {String} optName optional name of this instance
	 */
	this.konstructor = function( BidderSelectionModel, optName )
	{
		// init static DOM (must do this here instead of above!)
		if (!BidderModel.LoadXslDOM) BidderModel.LoadXslDOM = grvLoadXslDOM( kXSLPath+"AIMbidToJS.xsl" );
		var holderName = optName ? optName : "Bidder";
		this.souper( BidderSelectionModel, BidderModel.LoadXslDOM, holderName );

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

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

	/** return the parent Bidder isInactive flag @type boolean */
	this.inactive = function(){
		return this.bidder ? this.bidder[kBoolInactive] : null;
	}

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

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

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

		if (!this.cList.isValid()) return false;
		if (!this.sList.isValid()) return false;
		return true;
	}

	/** clear EDOs */
	this._resetEDOs = function( optBidder )
	{
		this.bidder = optBidder ? optBidder : null;

		if ( this.cList ) this.cList.reset();
		else this.cList = new EDOListModel( Contact );

		if ( this.sList ) this.sList.reset();
		else this.sList = new EDOListModel( Shipping );
	}

	/** set our Bidder object   but dont publish */
	this._setBidder = function(o){ this.bidder = o; }

	/** get a new Contacts list @type MVCListModel */
	this._newContacts  = function(){ return this.cList.reset(); }
	/** get a new Shipping list @type MVCListModel */
	this._newShipping = function(){ return this.sList.reset(); }

	/** return the debug details of "this" @type String */
	this.dump = function()
	{
		var		dStr = new Array();
				dStr.push( "BidderModel>>>[" );
				dStr.push( "Bidder="+(this.bidder?this.bidder.dump():"null") );
				dStr.push( "conts=" +(this.cList ?this.cList .dump():"null") );
				dStr.push( "ships=" +(this.sList ?this.sList .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 BidderSummary( this.bidder.key,
								  this.bidder[kStrIdCompany],
								  this.bidder[kCodeIdFICO],
								  0,
								  this.bidder[kBoolInactive] );
	}
	/** 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.bidder!=null; }

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

	/** return whether current EDO matches selection item "properties"
	 * @type boolean
	 * @param {EDOHolderSelectionItem} item selection menu item
	 */
	this.propMatch = function(item){ return this.getName ()==item.coName
										&&  this.inactive()==item.dead; }

	/** 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.bidder.pushPosts( posts );	//THIS **MUST** BE FIRST!!
		this.cList.pushPosts( posts );
		this.sList.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, Bidder.Factory, Shipping.Factory, Contact.Factory, this );
	}

	/** return the specified contact @type Contact
	 * @param {int} i index into contact list
	 */
	this._getContact = function( i ) {
	  return (i!=null && i>=0
	          && i<this.cList.getCount())
				 ? this.cList.getItem( i ) : null;
	}
	/** return the specified Shipping @type Shipping
	 * @param {int} i index into Shipping list
	 */
	this._getShipping = function( i ) {
	  return (i!=null && i>=0
	          && i<this.sList.getCount())
				 ? this.sList.getItem( i ) : null;
	}
	/** return the specified Bidder @type Bidder
	 * @param {int} i index into Bidder list
	 */
	this._getBidder = function( i ) {
	  return (i==0 && this.bidder)
	                ? this.bidder : null;
	}
	/** return reference to the specified editable domain object
	 * @param {BSCIndex} xi edo index
	 */
	this.getEDO  = function(xi){
		return xi.invoke( this, this._getBidder, this._getShipping, this._getContact );
	}

	/** insert a new Contact
	 * @param {int} i contact list index
	 * @param {EDO} edo the contact
	 */
	this._insertContact = function( i, edo ) {
	    this.cList.addBefore( i, edo );
	}
	/** insert a new Shipping
	 * @param {int} i Shipping list index
	 * @param {EDO} edo the Shipping
	 */
	this._insertShipping = function( xi ) {
	    this.sList.addBefore( i, edo );
	}
	/** 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._newBidder, this._insertShipping, this._insertContact, this.newEDO(xi) );
		return xi;
	}

	/** append a new Contact
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {int} i contact list index
	 * @param {EDO} edo the contact
	 */
	this._appendContact = function( i, edo ) {
	    return BSCIndex.Contact( this.cList.addItem( edo ) );
	}
	/** append a new Shipping
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {int} i Shipping list index
	 * @param {EDO} edo the Shipping
	 */
	this._appendShipping = function( i, edo ) {
	    return BSCIndex.Shipping( this.sList.addItem( edo ) );
	}
	/** create a new Bidder
	 * @return EDOIndex of new EDO
	 * @type EDOIndex
	 * @param {int} i Bidder list index
	 * @param {EDO} edo the Bidder
	 */
	this._newBidder = function( i, edo ) {
		//HACK!
		this._resetEDOs( edo );
		this.updateStamp();
		return BSCIndex.Bidder();
	}
	/** 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._newBidder, this._appendShipping, this._appendContact, 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.cList.toggleExpandAll( newVal );
			this.sList.toggleExpandAll( newVal );
			this.bidder.toggleExpand  ( newVal );
		}
		else edo.toggleExpand();
		this.updateStamp();
	}
}


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

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

		for (var i=0; i<N; ++i)
		  if (list.getItem(i).coName == bidderName
		  ||  list.getItem(i).key    == bidderKey) 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.findBidder( kBidderName, kBidderKey );
		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(BidderView,["Bidder object"])
.Extends(EDOView);
/**
 * @class This class produces a view of a {@link Bidder}.
 * @extends EDOView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function BidderView()
{
	/** @param {Bidder} bidder Bidder we are to observe
	 */
	this.konstructor = function( bidder ) {
		this.souper( bidder, BSCIndex.Bidder() );
	}

	this.preSelect = function() {
		this.sharedMenuSelect( gFICOSelected, kCodeIdFICO );
	}

	this.buildFields = function( HTML )
	{
		HTML.push( this.buildStrField( kStrIdCompany, 50, 50, false ) );
		HTML.push( this.buildPopField( kCodeIdFICO  ,         false, gFICOSelected ) );
		HTML.push( this.buildBoxField( kBoolInactive,         false ) );
	}
}

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

	this.buildFields = function( HTML )
	{
		HTML.push( this.buildStrField( kStrIdName   ,50,50,false) );
		HTML.push( this.buildStrField( kAddrIdStreet,50,80,true ) );
		HTML.push( this.buildStrField( kPhoneIdMain ,20,20,false) );
		HTML.push( this.buildStrField( kAddrIdCity  ,20,50,true ) );
		HTML.push( this.buildStrField( kPhoneIdFax  ,20,20,false) );
		HTML.push( this.buildUprField( kAddrIdState , 2, 2,true ) );
		HTML.push( this.buildStrField( kEMailIdAddr ,50,80,false) );
		HTML.push( this.buildStrField( kAddrIdZip   ,10,10,true ) );
		HTML.push( this.buildTxtField( kStrIdWireInst,2,100,255,false,2 ) );
	}
}

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

	this.buildFields = function( HTML )
	{
		HTML.push( this.buildStrField( kStrIdCompany,50,50,true  ) );
		HTML.push( this.buildStrField( kStrIdName   ,50,50,false ) );
		HTML.push( this.buildStrField( kAddrIdStreet,50,80,true  ) );
		HTML.push( this.buildStrField( kPhoneIdMain ,20,20,false ) );
		HTML.push( this.buildStrField( kAddrIdCity  ,20,50,true  ) );
		HTML.push( this.buildStrField( kPhoneIdFax  ,20,20,false ) );
		HTML.push( this.buildUprField( kAddrIdState , 2, 2,true  ) );
		HTML.push( this.buildStrField( kEMailIdAddr ,50,80,false ) );
		HTML.push( this.buildStrField( kAddrIdZip   ,10,10,false ) );
	}
}


Class(ContactListView,["EDO ListModel"])
.Extends(EDOListView);
/**
 * @class This class produces a view of a List of Contact EDOs.
 * @extends EDOListView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ContactListView()
{
	/** @param {EDOListModel} edoListModel EDO list we are to observe
	 */
	this.konstructor = function( edoListModel ) {
		this.souper( edoListModel, ContactView );
	}

	this.itemEDOIndex = function( index ) {
		return  BSCIndex.Contact( index );
	}
}

Class(ShippingListView,["EDO ListModel"])
.Extends(EDOListView);
/**
 * @class This class produces a view of a List of Shipping EDOs.
 * @extends EDOListView
 * @see #konstructor
 * @author Bruce Wallace  (PolyGlotInc.com)
 * @version 2.0
 */
function ShippingListView()
{
	/** @param {EDOListModel} edoListModel EDO list we are to observe
	 */
	this.konstructor = function( edoListModel ) {
		this.souper( edoListModel, ShippingView );
	}

	this.itemEDOIndex = function( index ) {
		return BSCIndex.Shipping( index );
	}
}


Class(BidderModelView,["Bidder 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 BidderModelView()
{
	/** @param {BidderModel} bidModel Bidder Contacts/Shippings we are to observe */
	this.konstructor = function( bidModel ) {
		this.souper( bidModel );
	}

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

	  if ( !this.model.bidder || this.model.bidder.inLimbo() )
	  {
		if (!grvWAITING())
		HTML.push( EDOView.ShellHTML( BSCIndex.Bidder(), Bidder ) );
	  }
	  else if ( this.model.bidder.isActive() )
      {
		HTML.push( this.embedHTML( vwID+".bidWdgt",
						new       BidderView( this.model.bidder ) ) );
 
		HTML.push( this.embedHTML( vwID+".coWdgt",
		                new  ContactListView( this.model.cList ) ) );

		HTML.push( this.embedHTML( vwID+".svWdgt",
		                new ShippingListView( this.model.sList ) ) );
      }
      else HTML.push( '<thead>This Bidder is deleted. You must Cancel, Save, or Undo.</thead>' );
	}
}
