/*
** Functions used to make HTML SELECT easier
*/

/*
 * Set all the values to either selected, unselected,
 * or toggle.
 *
 * select: The HTML SELECT element or id
 * setTo: AWPX_TRUE - Mark as selected
 *        AWPX_FALSE - Mark as unselected
 *        AWPX_TOGGLE - Toggle previous value
 */
function awpxSelectAll(select, setTo)
{
    var el = awpxGetElement(select);
    if(!el || !el.options)
    {
        return false;
    }
    for(var i=0; i<el.options.length; i++)
    {
        var optVal = el.options[i].selected;
        if(setTo == AWPX_TRUE || setTo == AWPX_TOGGLE && !optVal)
        {
            el.options[i].selected = true;
        }
        else if(setTo == AWPX_FALSE || setTo == AWPX_TOGGLE && optVal)
        {
            el.options[i].selected = false;
        }
    }
    return false;
}

/*
 * Moves the options from the source HTML SELECT to the
 * target HTML SELECT.  After the move, the selection is
 * place on the first option after the current selection.
 *
 * source: The HTML SELECT element or id to move from
 * target: The HTML SELECT element or id to move to
 * sort: AWPX_TRUE - Sort target after the move
 * all: AWPX_TRUE - Move not just selected, but all options.
 */
function awpxSelectMove(source, target, sort, all)
{
    var list = awpxSelectDeleteSelected(source, all);
    awpxSelectAdd(target, list, sort);
    return false;
}

/*
 * Deletes the selected options from the given HTML SELECT
 * and returns it.  The next unselected option will be selected
 * when this returns.
 *
 * source: The HTML SELECT element or id to move from
 * deleteAll: AWPX_TRUE - Delete all options, not just selected ones
 * keepSelection: AWPX_FALSE - Resets the selection
 */
function awpxSelectDeleteSelected(source, deleteAll, keepSelection)
{
    var el = awpxGetElement(source);

    var nextSelect;
    var deleteList = new Array();
    var keepList = new Array();
    for (var i=0; i<el.options.length; i++)
    {
        var opt = el.options[i];
        if(deleteAll || opt.selected)
        {
            deleteList[deleteList.length] = opt;
            if(!nextSelect && i < el.options.length - 1 && !el.options[i+1].selected)
            {
                nextSelect = el.options[i+1];
            }
        }
        else
        {
            keepList[keepList.length] = opt;
        }
    }
    el.options.length = 0;
    for (var i=0; i<keepList.length; i++)
    {
        el.options[el.options.length] = keepList[i];
    }

    /* Turn on selection */
    if(!keepSelection && nextSelect)
    {
        nextSelect.selected = true;
    }

    return deleteList;
}

/*
 * Moves the selected entries up or down
 * up: AWPX_TRUE - Move up one
 *     AWPX_FALSE - Move down one
 */
function awpxSelectMoveOrder(list, up)
{
    var el = awpxGetElement(list);

    var origList = new Array();
    for(var i=0; i<el.options.length; i++)
    {
        origList[origList.length] = el.options[i];
    }

    var newList = _awpxSelectMoveOrder(origList, up);

    /* Copied moved list */
    el.options.length = 0;
    for(var i=0; i<newList.length; i++)
    {
        el.options[el.options.length] = newList[i];
    }
}

function _awpxSelectMoveOrder(list, up)
{
    if(!up)
    {
        list = list.reverse();
    }

    var movedList = new Array();
    for(var i=0; i<list.length; i++)
    {
        if(i < list.length - 1)
        {
            if(!list[i].selected && list[i+1].selected)
            {
                movedList[movedList.length] = list[i+1];
                var subList = new Array();
                subList[0] = list[i];
                if(list.length > i + 2)
                {
                    subList = subList.concat(list.slice(i+2));
                }
                movedList = movedList.concat(_awpxSelectMoveOrder(subList, AWPX_TRUE));
                if(!up)
                {
                    movedList = movedList.reverse();
                }
                return movedList;
            }
        }
        movedList[movedList.length] = list[i];
    }

    if(!up)
    { 
        movedList = movedList.reverse();
    }

    return movedList;
}       

/*
 * Adds the given options to the HTML SELECT element.  If the 
 * target list has duplicates (by label), then they are not 
 * added, but returned.
 *
 * All options are added as unselected.
 *
 * target: The HTML SELECT element or it to add to
 * list: The options to add
 * sort: AWPX_TRUE - Sort SELECT after add
 */
function awpxSelectAdd(target, list, sort)
{
    var ret = new Array();
    if(!list)
    {
        return ret;
    }

    var el = awpxGetElement(target);
    el.selectedIndex = -1;
    for (var i=0; i<list.length; i++)
    {
        var performAdd = true;
        var newOption = list[i];
        if (el.options && el.options.length > 0)
        {
            for (var j=0; j<el.options.length; j++)
            {
                if (el.options[j].text == newOption.text)
                {
                    ret[ret.length] = newOption;
                    performAdd = false;
                    break;
                }
            }
        }
        if (performAdd)
        {
            if (typeof newOption == 'string')
            {
                newOption = new Option(newOption, newOption);
            }
            newOption.selected = false;
            newOption.defaultSelected = false;
            el.options[el.options.length] = newOption;
        }
    }

    if(sort)
    {
        awpxSelectSort(el);
    }
    return ret;
}

/*
 * Sort the given HTML SELECT options
 * sortByValue: AWPX_TRUE - sort by option value
 *              AWPX_FALSE - sort by option label
 */
function awpxSelectSort(select, sortByValue)
{
    var el = awpxGetElement(select);

    var deletedList = awpxSelectDeleteSelected(el, AWPX_TRUE, AWPX_TRUE);
    if(sortByValue)
    {
      deletedList.sort(awpxSelectOptionValueComparator);
    }
    else
    {
      deletedList.sort(awpxSelectOptionComparator);
    }

    for (var i=0; i<deletedList.length; i++)
    {
        var newOption = deletedList[i];
        el.options[el.options.length] = newOption;
    }
    return false;
}

/*
 * Comparator function used to compare HTML OPTION tags
 * by value
 */
function awpxSelectOptionValueComparator(a, b)
{
    var aL = a.value.toLowerCase();
    var bL = b.value.toLowerCase();
    if (aL == bL) return 0;
    if (aL < bL) return -1;
    return 1;
}

/*
 * Comparator function used to compare HTML OPTION tags
 * by label
 */
function awpxSelectOptionComparator(a, b)
{
    var aL = a.text.toLowerCase();
    var bL = b.text.toLowerCase();
    if (aL == bL) return 0;
    if (aL < bL) return -1;
    return 1;
}
