// JS driver for the vocabulary picker

function setupDiv(divElem, formElem, vocab, currValue)
{
    divElem.comboCount = 0;
    divElem.combos = [];
    divElem.formElem = formElem;
    if (currValue)
        _setValue(divElem,vocab,currValue);
    else
        _setupCombo(divElem, vocab, 0,null);
}

///////////////// Internal functions /////////////////////////

// Recursively search for the given item ID in arr. When found, returns an array
// of parent objects with the found object as its last item.
function _findItem(arr, itemID, stack)
{
    var sl = stack.length;
    for (var j=0; j<arr.length; j++)
    {
        if (!arr[j]) break;         //IE6 sometimes misreports array.length
        if (arr[j].id == itemID)
        {
            stack.length = sl;      //truncate the last item on the stack, if present
            stack[sl] = arr[j];
            return stack;
        }
        if (arr[j].children && arr[j].children.length > 0)
        {
            stack.length = sl;
            stack[sl] = arr[j];
            var ret = _findItem(arr[j].children, itemID, stack);
            if (ret != null) return ret;        //found it!
        }
    }
    return null;
}

//set the value in the specified div to the specified vocabulary ID.
//note that this function does linear tree search, which means that it may be
//slow for large trees. however, it generally only has to run once.
function _setValue(div, arr, itemID)
{
    var aVoc;
    aVoc = _findItem(arr, itemID, []);
    if (aVoc == null) return;       //couldn't find the item
    _setupCombo(div, arr, 0, null);
    for (var i=0; i<aVoc.length; i++)
    {
        for (var j=0; j < div.combos[i].options.length; j++)
        {
            if (div.combos[i].options[j].value == aVoc[i].id)
            {
                div.combos[i].options[j].selected = true;
                if (aVoc[i].children && aVoc[i].children.length > 0)
                    _setupCombo(div, aVoc[i].children, i+1, aVoc[i].id);                
            }
        }
    }
    div.selectedVocab = itemID;
}

//insert a combobox into the specified div with members from the given array
function _setupCombo(div, arr, lvl,parentID)
{
    var cbo;
    if (div.comboCount > lvl)
    {
        for (var i=lvl; i<div.comboCount; i++)
        {
            div.removeChild(div.combos[i]);
        }
        div.comboCount = lvl;
    }
    if (arr == null) return;
    cbo = div.appendChild(document.createElement("select"));
    div.combos[div.comboCount] = cbo;
    div.comboCount++;
    cbo.lvl = lvl;
    _populateComboItems(cbo, arr, lvl,parentID);
    cbo.onchange = function()
    {
        div.formElem.value = this.options[this.selectedIndex].value;
        //collapse if the user selects --choose--
        if (!this.options[this.selectedIndex].arrItem)
        {
            _setupCombo(this.parentNode, null,this.lvl+1);  
        }
        else if (this.options[this.selectedIndex].arrItem.children &&
            this.options[this.selectedIndex].arrItem.children.length > 0)
            _setupCombo(this.parentNode, this.options[this.selectedIndex].arrItem.children, this.lvl+1,
                       this.options[this.selectedIndex].arrItem.id);
    }
}

function _populateComboItems(cbo, arr, lvl, parentID)
{
    //'choose' gets the parent id so that selecting it generates the parent vocabulary
    //as the current selection
    cbo.options[0] = new Option("---Choose---",parentID);
    for (var j=0; j<arr.length; j++)
    {
        if (!arr[j]) break;         //IE6 sometimes misreports array.length
        cbo.options[j+1] = new Option(arr[j].name, arr[j].id);
        cbo.options[j+1].arrItem = arr[j];
    }
}

