﻿(function() {

    var FORMS = sbs.register("sbs.forms");
    var LISTS = sbs.register("sbs.forms.lists");

    /*
    sbs.forms.lists.addListOption
    adds a new option to a select list

    args
    1 - list
    *required*
    the select list to add the option to
    
    2 - value
    *required*
    the value (and if name is not present, name) of the option
    
    3 - name
    *optional* ([value])
    the name of the option
    
    4 - title
    *optional*
    the title of the option
    
    5 - isSelected
    *optional* (false)
    whether or not this option should be considered selected
    
    returns
    the list item that has been added
    */
    LISTS.addListOption = function(list, value, name, title, isSelected) {
        if (name == null) name = value;
        if (isSelected == null) isSelected = false;

        var newItem = document.createElement('option');
        newItem.value = value;
        newItem.text = name;
        if (title)
            newItem.title = title;
        newItem.selected = isSelected;

        try { list.add(newItem, null); }
        catch (err1) {
            try { list.add(newItem); }
            catch (err2) {
                return null;
            }
        }

        return newItem;
    };

    /*
    sbs.forms.lists.clearList
    clears a select list
    
    args
    1 - list
    *required*
    the select list to clear
    */
    LISTS.clearList = function(list) {
        list.options.length = 0;
    };


    /*
    sbs.forms.lists.listContains
    checks if a list contains an item with a specified value
    
    args
    1 - list
    *required*
    the select list to parse
    
    2 - value
    *required*
    the value to search for
    
    returns
    true or false
    */
    LISTS.doesListContain = function(list, value) {
        for (var i = 0, j = list.options.length; i < j; i++) {
            if (list.options[i].value == value) return true;
        }
        return false;
    };

    /*
    sbs.forms.lists.getSelectedValues
    gets an array of the values of a list's selected items
    
    args
    1 - list
    *required*
    the select list to parse
    
    returns
    an Array of values
    */
    LISTS.getSelectedValues = function(list) {
        var items = new Array();
        for (var i = 0, j = list.options.length; i < j; i++) {
            if (list.options[i].selected) {
                items.push(list.options[i].value);
            }
        }
        return items;
    };

    /*
    sbs.forms.lists.removeListOption
    removes an option from a select list

    args
    1 - list
    *required*
    the select list to add the option to
    
    2 - value
    *required*
    the value of the option to remove
    
    returns
    true if item was removed
    false if item was not removed
    */
    LISTS.removeListOption = function(list, value) {
        for (var i = 0, j = list.options.length; i < j; i++) {
            if (list.options[i].value == value) {
                list.remove(i);
                return true;
            }
        }
        return false;
    };

    /*
    sbs.forms.lists.populateList
    fills a list with data from an array of objects

    args
    1 - list
    *required*
    the select list to populate
    
    2 - objectArray
    *required*
    the array of objects to repopulate the list with
    
    3 - valueSelector
    *optional* ("value")
    the property name or selector function of each item in the array to use as value
    
    4 - nameSelector
    *optional* ("name")([value])
    the property name or selector function of each item in the array to use as name
    
    5 - titleSelector
    *optional*
    the property name or selector function of each item in the array to use as title
    
    6 - selectedValue
    *optional*
    the value that will be selected once the list is populated
    */
    LISTS.populateList = function(list, objectArray, valueSelector, nameSelector, titleSelector, selectedValue) {
        if (!objectArray || !objectArray.length || objectArray.length == 0)
            return;

        if (valueSelector === null) valueSelector = "value";
        if (typeof valueSelector == 'string') {
            var valueProperty = valueSelector;
            valueSelector = function(member) { return member[valueProperty]; };
        }

        if (nameSelector === null) nameSelector = "name";
        if (typeof nameSelector == 'string') {
            var nameProperty = nameSelector;
            nameSelector = function(member) { return member[nameProperty]; };
        }

        if (!titleSelector) titleSelector = function(member) { return null; };
        if (typeof titleSelector == 'string') {
            var titleProperty = titleSelector;
            titleSelector = function(member) { return member[titleProperty]; };
        }

        if (typeof nameSelector(objectArray[0]) == 'undefined') nameSelector = valueSelector;

        var selectTester = (selectedValue === null) ? (function(member) { return false; }) : (function(member) { return valueSelector(member) == selectedValue; });

        for (var i = 0, j = objectArray.length; i < j; i++) {
            sbs.forms.lists.addListOption(
                  list
                , valueSelector(objectArray[i])
                , nameSelector(objectArray[i])
                , titleSelector(objectArray[i])
                , selectTester(objectArray[i])
                );
        }
    };

    /*
    sbs.forms.lists.fillList
    fills a list with data from an array of strings

    args
    1 - list
    *required*
    the select list to populate
    
    2 - optionArray
    *required*
    the array of strings to repopulate the list with
    */
    LISTS.fillList = function(list, optionArray) {
        for (var i = 0, j = optionArray.length; i < j; i++) {
            sbs.forms.lists.addListOption(
                  list
                , optionArray[i]
                );
        }
    };

    /*
    sbs.forms.lists.selectItem
    selects an option in a list

    args
    1 - list
    *required*
    the select list to parse
    
    2 - value
    *required*
    the list option with a value or name that should be selected
    
    returns
    the index where the selected option resides
    -1 if no item was found
    */
    LISTS.selectItem = function(list, value) {
        for (var i = 0, j = list.options.length; i < j; i++) {
            if (list.options[i].value == value || list.options[i].innerHTML == value) {
                list.selectedIndex = i;
                return i;
            }
        }
        return -1;
    };

    /*
    sbs.forms.lists.selectItems
    selects options in a multi-select list

    args
    1 - list
    *required*
    the select list to parse
    
    2 - value
    *required*
    the list options with a value or name that should be selected
    
    3 - overwrite
    *optional*
    if true, all old selections will be overwritten
    */
    LISTS.selectItems = function(list, values, overwrite) {
        for (var i = 0, j = list.options.length; i < j; i++) {
            if (overwrite)
                list.options[i].selected = false;

            for (var x = 0, y = values.length; x < y; x++) {
                if (list.options[i].value == values[x] || list.options[i].innerHTML == values[x]) {
                    list.options[i].selected = true;
                    break;
                }
            }
        }
    };

})();

/* TESTS */
/*
<html>
<select>
<option value="init" selected="selected">init</option>
<option value="init2">init2</option>
<option value="init3">init3</option>
</select>
</html>
sbs.forms.lists.addListOption(item, 'gravy', 'sweet', true);
sbs.forms.lists.clearList(item);
document.writeln('init : ' + sbs.forms.lists.doesListContain(item, 'init'));
document.writeln('nopes : ' + sbs.forms.lists.doesListContain(item, 'nopes'));
sbs.forms.lists.removeListOption(item, 'init2');
var obj = {
"values": [
{ "name": "one", "id": 1 }
, { "name": "two", "id": 2 }
, { "name": "three", "id": 3 }
]
};
sbs.forms.lists.populateList(item, obj.values, 'id', 'name', 2);
sbs.forms.lists.selectListValue(item, 'init3');
*/