/**
 * $Id: interface.js 64367 2009-02-20 01:56:36Z kchiu $
 * $Author: kchiu $
 * $Revision: 64367 $
 * $Name$
 * $Date: 2009-02-19 17:56:36 -0800 (Thu, 19 Feb 2009) $
 *
 *
 *
 * This Interface JavaScript library serves to implement
 * a sort-of hacked interface extension to the standard
 * JavaScript language.
 *
 * The Interface function is never intended to be
 * invoked directly but rather in a prototype chain.
 *
 * Documentation will be available at:
 *
 * http://wiki.pricegrabber.com/moin.cgi/PhilipSnyder
 *
 *
 *
 * @version    $Revision: 64367 $
 * @author     Philip Snyder <philip@pricegrabber.com>
 * @copyright  Copyright &copy; 2006, Philip Snyder, PriceGrabber.com
 */

/**
 * Interface Constructor / Definition
 *
 * This is NOT intended to be instantiated directly. See
 * documentation for a complete explanation.
 *
 * @access public
 * @since  v1.1
 * @return Interface
 */
function Interface() {
    this.implement = Interface_Implement;
    return this;
}

/**
 * Confirms complete implementation of passed in Interface function reference.
 *
 * This method checks the object in question and validates that it has
 * either implemented or borrowed every method & variable defined in
 * the interfaces it claims to implement.
 *
 * @access public
 * @since  v1.1
 * @return void
 */
function Interface_Implement(ifaceRef) {
    var tmpObj  = new ifaceRef();
    var objName = (this.constructor+'').substr(('function ').length, (this.constructor+'').indexOf('(') - 'function '.length);
    for (var prop in tmpObj) {
        var typeCheck = false;
        var isFunc    = false;
        eval('isFunc    = (typeof(tmpObj.'+prop+') == "function");');
        eval('typeCheck = (typeof(this.'+prop+')   == typeof(tmpObj.'+prop+'));');
        if (prop != 'implement' && !typeCheck) {
            if (isFunc) throw new Error(objName+'.'+prop+"() not implemented!");
            else        throw new Error(objName+'.'+prop+" is either a wrong type or missing.");
        }
    }
}

/**
 * Attach the implement() method to our BaseObject as
 * well, and all classes extending BaseObjects will have
 * it available to them (and all at the cost of 1
 * function loaded into memory).
 */
if (typeof(BaseObject) == 'function') BaseObject.prototype.implement = Interface_Implement;
