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

var __CFEXTENDEDSELECT_ERROR_ID = "invalid CFExtendedSelect id";

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

var __cfExtendedSelectMap = {};

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

// CFExtendedSelect

function CFExtendedSelect(id, selectRadioButtonId, selectBoxId,
                          textRadioButtonId, textBoxId, textBoxLabelId,
                          hiddenId, value)
{
    CFWidget.call(this, id);
    var hiddenInput = cfElementGet(hiddenId);
    var selectBox = cfElementGet(selectBoxId);
    var selectRadioButton = cfElementGet(selectRadioButtonId);
    var textBox = cfElementGet(textBoxId);
    var textRadioButton = cfElementGet(textRadioButtonId);
    this.__hiddenInput = hiddenInput;
    this.__selectBox = selectBox;
    this.__selectRadioButton = selectRadioButton;
    this.__textBox = textBox;
    this.__textRadioButton = textRadioButton;
    this.setValue(value);
    if (textBoxLabelId.length) {
        cfElementRemoveClass(cfElementGet(textBoxLabelId),
                             CFELEMENT_HIDDEN_CLASS);
    }
    cfElementRemoveClass(selectBox, CFELEMENT_HIDDEN_CLASS);
    cfElementRemoveClass(selectRadioButton, CFELEMENT_HIDDEN_CLASS);
    cfElementRemoveClass(textRadioButton, CFELEMENT_HIDDEN_CLASS);
    var name = hiddenInput.name;
    hiddenInput.name = textBox.name;
    textBox.name = name;
    __cfExtendedSelectMap[id] = this;
    var f = cfEventHandlerCreate(this.__handleSelectBoxUpdate.bind(this));
    cfSelectSetChangeCallback(selectBox, f);
    f = cfEventHandlerCreate(this.__handleSelectRadioButtonUpdate.bind(this));
    cfRadioSetChangeCallback(selectRadioButton, f);
    f = cfEventHandlerCreate(this.__handleTextBoxUpdate.bind(this));
    textBox.onblur = f;
    f = cfEventHandlerCreate(this.__handleTextRadioButtonUpdate.bind(this));
    cfRadioSetChangeCallback(textRadioButton, f);
}

CFExtendedSelect.extendClasses(CFWidget);

CFExtendedSelect.prototype.__handleSelectBoxUpdate = function()
{
    this.setValue(cfSelectGetValue(this.__selectBox));
    this.__triggerEvent(CFWIDGET_EVENT_USER_UPDATE);
}

CFExtendedSelect.prototype.__handleSelectRadioButtonUpdate = function()
{
    if (this.__selectRadioButton.checked) {
        this.setValue(cfSelectGetValue(this.__selectBox));
    } else {
        this.setValue(this.__textBox.value, true);
    }
    this.__triggerEvent(CFWIDGET_EVENT_USER_UPDATE);
}

CFExtendedSelect.prototype.__handleTextBoxUpdate = function()
{
    this.setValue(this.__textBox.value, true);
    this.__triggerEvent(CFWIDGET_EVENT_USER_UPDATE);
}

CFExtendedSelect.prototype.__handleTextRadioButtonUpdate = function()
{
    if (this.__textRadioButton.checked) {
        this.setValue(this.__textBox.value, true);
    } else {
        this.setValue(cfSelectGetValue(this.__selectBox));
    }
    this.__triggerEvent(CFWIDGET_EVENT_USER_UPDATE);
}

CFExtendedSelect.prototype.getSelectedIndex = function()
{
    return this.isExtendedValue() ? -1 : this.__selectBox.selectedIndex;
}

CFExtendedSelect.prototype.getValue = function()
{
    return this.__value;
}

CFExtendedSelect.prototype.isExtendedValue = function()
{
    return this.__isExtendedValue;
}

CFExtendedSelect.prototype.setValue = function(value, forceText)
{
    var selectBox = this.__selectBox;
    var textBox = this.__textBox;
    if (! value) {
        value = '';
    }
    var useSelect = (! forceText) && cfSelectSetValue(selectBox, value, true);
    if (useSelect) {
        selectBox.disabled = false;
        this.__selectRadioButton.checked = true;
        textBox.disabled = true;
        textBox.readOnly = true;
        this.__textRadioButton.checked = false;
    } else {
        selectBox.disabled = true;
        this.__selectRadioButton.checked = false;
        textBox.disabled = false;
        textBox.readOnly = false;
        textBox.value = value;
        this.__textRadioButton.checked = true;
    }
    this.__hiddenInput.value = value;
    this.__isExtendedValue = ! useSelect;
    this.__value = value;
}

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

function cfExtendedSelectCreate(arg)
{
    return new CFExtendedSelect(arg.id, arg.selectRadioButtonId,
                                arg.selectBoxId, arg.textRadioButtonId,
                                arg.textBoxId, arg.textBoxLabelId, arg.hiddenId,
                                arg.value);
}

function cfExtendedSelectGet(id)
{
    var select = __cfExtendedSelectMap[id];
    if (! select) {
        return cfErrorTrigger("cfExtendedSelectGet: '" + id + "': " +
                              __CFEXTENDEDSELECT_ERROR_ID);
    }
    return select;
}
