////////////////////////////////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////////////////////////////////

var __CFWIDGET_ERROR_ID = "invalid widget id";
var __CFWIDGET_ERROR_REGISTERED = "this widget id is already registered";

var CFWIDGET_EVENT_DELETE = "delete";
var CFWIDGET_EVENT_DISABLE = "disable";
var CFWIDGET_EVENT_ENABLE = "enable";
var CFWIDGET_EVENT_HIDE = "hide";
var CFWIDGET_EVENT_MOUSE_OUT = "mouseOut";
var CFWIDGET_EVENT_MOUSE_OVER = "mouseOver";
var CFWIDGET_EVENT_SHOW = "show";
var CFWIDGET_EVENT_USER_SELECT = "userSelect";
var CFWIDGET_EVENT_USER_UPDATE = "userUpdate";

////////////////////////////////////////////////////////////////////////////////
// Static Variables
////////////////////////////////////////////////////////////////////////////////

var __cfWidgetMap = {};

////////////////////////////////////////////////////////////////////////////////
// Classes
////////////////////////////////////////////////////////////////////////////////

function CFWidget(id)
{
    if (__cfWidgetMap[id]) {
        return cfErrorTrigger("CFWidget: '" + id + "': " +
                              __CFWIDGET_ERROR_REGISTERED);
    }
    this.__widgetElement = cfElementGet(id);
    this.__widgetEnabled = true;
    this.__widgetEventHandlerSet = new CFEventHandlerExpandedSet();
    this.__widgetId = id;
    __cfWidgetMap[id] = this;
}

CFWidget.prototype.__triggerEvent = function(eventId)
{
    this.__widgetEventHandlerSet.execute(eventId);
}

CFWidget.prototype.addEventHandler = function()
{
    var handlerSet = this.__widgetEventHandlerSet;
    handlerSet.add.apply(handlerSet, arguments);
}

CFWidget.prototype.disable = function()
{
    if (this.__widgetEnabled) {
        this.__widgetEnabled = false;
        this.__triggerEvent(CFWIDGET_EVENT_DISABLE);
    }
}

CFWidget.prototype.discardEventHandler = function(eventId, handler)
{
    return this.__widgetEventHandlerSet.remove(eventId, handler);
}

CFWidget.prototype.enable = function()
{
    if (! this.__widgetEnabled) {
        this.__widgetEnabled = true;
        this.__triggerEvent(CFWIDGET_EVENT_ENABLE);
    }
}

CFWidget.prototype.getDimensions = function(ignoreError)
{
    return cfElementGetDimensions(this.__widgetElement, ignoreError);
}

CFWidget.prototype.getDocumentPosition = function(ignoreError)
{
    return cfElementGetDocumentPosition(this.__widgetElement, ignoreError);
}

CFWidget.prototype.getElement = function()
{
    return this.__widgetElement;
}

CFWidget.prototype.getId = function()
{
    return this.__widgetId;
}

CFWidget.prototype.isEnabled = function()
{
    return this.__widgetEnabled;
}

CFWidget.prototype.refresh = function()
{
    // Nothing to be done
}

CFWidget.prototype.removeEventHandler = function(eventId, handler)
{
    return this.__widgetEventHandlerSet.remove(eventId, handler);
}

////////////////////////////////////////////////////////////////////////////////
// Public API
////////////////////////////////////////////////////////////////////////////////

function cfWidgetGet(id)
{
    var widget = __cfWidgetMap[id];
    if (! widget) {
        return cfErrorTrigger("cfWidgetGet: '" + id + "': " +
                              __CFWIDGET_ERROR_ID);
    }
    return widget;
}
