/**
 * @fileoverview 
 * <p>This library is designed to encapsulate mls objects, plus a collection to house them.
 *    The collection allows for programmatic addition of mls objects.  Those objects can be 
 *    manually populated and added during page load.  The mls objects are also remote capable as
 *    they extend xhr.  They can be loaded dynamically.  The collection will perform this action
 *    for the user as the mls is requested, if a lookup url is provided. 
 *  </p>
 * @author Robert D. Rice
 */

// vc_id = "$Id: mls.js 12623 2009-09-21 21:46:29Z robert $"

/**
 * Container for the mls collection.
 * Holds onto the cache of mls objects, plus
 * provides state change support
 */
function MLSCollection( ) {
    // scs attributes
    this.listeners = new Array( );
    this.name = "mls collection";
    this.state = STATE_CHANGE_STATE_UNINITIALIZED;
    this.status = STATE_CHANGE_STATUS_OK;
    this.stateChange = MLSCollectionStateChange;

    // attributes
    this.collection = new Object( );
    this.url = null;

    // methods
    this.add = MLSCollectionAdd;
    this.retrieve = MLSCollectionRetrieve;
    this.initialize = MLSCollectionInitialize;
}
MLSCollection.prototype =  new StateChangeSupport( );

/**
 * state change method.
 * for registration on individual mls objects.
 * will in turn report back to collection listeners.
 * @param scs
 */
function MLSCollectionStateChange( scs ) {
    var size = this.listeners.length;
    for ( var i = 0; i < size; i++ ) {
	this.listeners[ i ].stateChange( scs );
    }
}

/**
 * collection method to add an mls
 * @param mls object, must have an id for storage
 */
function MLSCollectionAdd( mls ) {
    if ( mls && mls.id ) {
	this.collection[ mls.id ] = mls;
    }
}

/**
 * collection method to retrieve an mls
 * @param id of the mls
 * @return mls object if found, null otherwise
 *   this method will trigger a dynamic load of the mls if enabled
 */
function MLSCollectionRetrieve( id ) {
    var rval = null;

    if ( id && id != "" ) {
	rval = this.collection[ id ];

	// dynamic load if required and available
	if ( !rval && this.url ) {
	    var mls = new MLS( id );
	    this.add( mls );
	    mls.addListener( this );
	    mls.setUrl( this.url );
	    mls.update( );
            rval = mls;
	}
    }

    return rval;
}

/**
 * initialize the mls collection with a lookup url
 * @param lookup url, automatic population of collection
 */
function MLSCollectionInitialize( url ) {
    this.url = url;
}

/**
 * Constructor for an mls object
 * @constructor
 * @param id of the mls
 * @param name of the mls, short name, abbreviation
 * @param description, long name
 * @param cma
 * @param disclaimer
 * @param updateDate
 * @return new mls instance
 */
function MLS( id, name, description, cma, disclaimer, updateDate ) {
    // StateChangeSupport
    this.listeners = new Array( );
    this.name = "mls";
    this.state = STATE_CHANGE_STATE_UNINITIALIZED;
    this.status = STATE_CHANGE_STATUS_OK;
    this.stateChange = MLSStateChange;
    this.addListener( this );

    // attributes
    this.id = id ? id : -1;
    // using abbrev. to hold name, as that attribute was consumed by scs
    this.abbreviation = name ? name : "";
    this.description = description ? description : "";
    this.cma = cma ? cma : "";
    this.disclaimer = disclaimer ? disclaimer : "";    
    this.updateDate = updateDate ? updateDate : "";  
    this.url = null;

    // methods
    this.toString = MLSToString;
    this.displayMLSCredit = MLSDisplayMLSCredit;
    this.setUrl = MLSSetUrl;
    this.update = MLSUpdate;
}
MLS.prototype = new XHR( );

/**
 * internal stateChange method to update self
 * this is the key to the remote object
 * @param StateChangeSupport object
 */
function MLSStateChange( xhr ) {
    if ( xhr.success( ) ) {
	var xml = xhr.responseXML( );
        this.id = XHRFirstElementsValueByName( xml, "id", this.id, true );
        this.abbreviation = XHRFirstElementsValueByName( xml, "name", this.abbreviation );
        this.description = XHRFirstElementsValueByName( xml, "description", this.description );
        this.cma = XHRFirstElementsValueByName( xml, "cma", this.cma, true );
        this.updateDate = XHRFirstElementsValueByName( xml, "updateDate", this.updateDate );
        this.disclaimer = XHRFirstElementsValueByName( xml, "disclaimer", this.disclaimer );
	// logMessage( this );
    }
}

/**
 * toString method
 * @return string representation
 */
function MLSToString( ) {
    var rval = "{";
    rval = rval + " id:" + this.id;
    rval = rval + " name:" + this.abbreviation;
    rval = rval + " description:" + this.description;
    rval = rval + " cma:" + this.cma;
    rval = rval + " updateDate:" + this.updateDate;
    rval = rval + " disclaimer:" + this.disclaimer;
    rval = rval + " }";
    return rval;
}

/**
 * display the mls credit
 * @param string representing the compnay to append to the credit, optional
 * @return string representation of the mls credit.
 */
function MLSDisplayMLSCredit( company ) {
    var rval = "";

    if ( this.description && this.description != "" ) {
	rval = this.description;
    }
    if ( company && company != "" ) {
	rval = rval != "" ? rval + " / " + company : company;
    }

    rval = "Courtesy of: " + rval;

    return rval;
}

/**
 * set an lookup base url
 * @param url
 */
function MLSSetUrl( url ) {
    this.url = url;
}

/**
 * method to trigger an internal update
 * this will only take action if a lookup base url has been set.
 * @see setUrl
 */
function MLSUpdate( ) {
    if ( this.url ) {
	this.setAction( this.url + "&mls=" + this.id );
	this.run( null );
    }
}

/** mls collection library methods begin, provided for convenience */

// the mls collection, this constructed and held globally for convenience
var MLS_COLLECTION = new MLSCollection( );

/**
 * collection method to add an mls
 * @param mls object, must have an id for storage
 */
function addMLS( mls ) {
    MLS_COLLECTION.add( mls );
}

/**
 * collection method to retrieve an mls
 * @param id of the mls
 * @return mls object if found, null otherwise
 *   this method will trigger a dynamic load of the mls if enabled
 */
function retrieveMLS( id ) {
    return MLS_COLLECTION.retrieve( id );
}

/**
 * initialize the mls collection with a lookup url
 * @param lookup url, automatic population of collection
 */
function initializeMLSCollection( url ) {
    MLS_COLLECTION.initialize( url );
}

/**
 * register for state change notifications
 */
function addMLSCollectionStateChangeListener( listener ) {
    MLS_COLLECTION.addListener( listener );
}

