var comparisonTool = function() {
    
    var items = new Array(); // all items (array of objects)
    var activeItems = new Array(-1, -1, -1); // indexes of the 3 items currently being displayed
    
    /*
     * initialize data from XML file
     */
    function init(xmlFile) {

        // parse items from XML file
        $.get(xmlFile, function(xmlDoc) {

            // initialize master list of all items
            $('item', xmlDoc).each(function() {
                var item = { id: $(this).attr('id') };
                $('*', this).each(function() {
                    item[this.tagName] = $(this).text();
                });
                items.push(item);
            });
    
            // populate item choosers in HTML (lists of clickable items)
            $('#c1_choose, #c2_choose, #c3_choose').each(function(i) {
                for (var j = 0; j < items.length; j++) {
                    $('ul', this).append('<li><a href="#">' + items[j].name + '</a></li>');
                    $('ul > li > a:last', this).click(function() {
                        var itemIndex = $(this).parents('ul:first').children().index( $(this).parent() );
                        showItem(itemIndex, i);
                        return false;
                    });
                }
            });
            
            // set initial item(s) to compare based on query string
            var qs = querystringAsObject();
            if (qs.c1) { showItem(getItemIndex(qs.c1), 0) }
            if (qs.c2) { showItem(getItemIndex(qs.c2), 1) }
            if (qs.c3) { showItem(getItemIndex(qs.c3), 2) }

        });

        // close an active item on click of close icon
        $('#c1_close, #c2_close, #c3_close').each(function(i) {
            $(this).click(function() {
                closeItem(i);
                return false;
            });
        });

    }
    
    /*
     * show the specified item in the specified column
     */
    function showItem(itemIndex, columnIndex) {
        
        if (itemIndex < 0 || columnIndex < 0) return;
        
        // first close currently active item in the column, if any
        if (activeItems[columnIndex] >= 0) {
            closeItem(columnIndex);
        }

        // hide item chooser in the column; show close icon and item name
        var idPrefix = '#c' + (columnIndex + 1) + '_';
        $(idPrefix + 'choose').slideUp(500);
        $(idPrefix + 'close').show();
        $(idPrefix + 'item_name').show();
        
        // remove item as choice from other columns
        $('#c1_choose, #c2_choose, #c3_choose').not(idPrefix + 'choose').each(function() {
            $('ul li', this).eq(itemIndex).hide();
        });

        // show item properties (in elements with ids of the format "c<column_number>_item_<property_name>")
        var item = items[itemIndex];
        for (var prop in item) {
            $(idPrefix + 'item_' + prop)
                .html(item[prop])
                .trigger('htmlchange.compare'); // custom event so container page can easily act on any individual property change
        }

        // update active item
        activeItems[columnIndex] = itemIndex;
        
    }
    
    /*
     * close/hide the item in the specified column
     */
    function closeItem(columnIndex) {

        if (columnIndex < 0) return;
        
        // hide close icon and item name; show item chooser
        var idPrefix = '#c' + (columnIndex + 1) + '_';
        $(idPrefix + 'close').hide();
        $(idPrefix + 'item_name').hide();
        $(idPrefix + 'choose').slideDown(500);
        
        // add item as choice to other columns
        var itemIndex = activeItems[columnIndex];
        $('#c1_choose, #c2_choose, #c3_choose').not(idPrefix + 'choose').each(function() {
            $('ul li', this).eq(itemIndex).show();
        });

        // empty item properties (from elements with ids of the format "c<column_number>_item_<property_name>")
        var item = items[activeItems[columnIndex]];
        for (var prop in item) {
            $(idPrefix + 'item_' + prop)
                .html('&nbsp;')
                .trigger('htmlchange.compare'); // custom event so container page can easily act on any individual property change
        }

        // update active item
        activeItems[columnIndex] = -1;

    }
    
    /*
     * return the index of the item specified by id; returns -1 if not found
     */
    function getItemIndex(id) {
        for (var i = 0; i < items.length; i++) {
            if (items[i].id == id) {
                return i;
            }
        }
        return -1;
    }

    /*
     * parse query string as object (associative array)
     * - only supports singular occurrences of names
     * - if multiple occurrences of the same name are found, the last occurrence will take precedence
     */
    function querystringAsObject() {
        var obj = {};
        var pairs = window.location.search.substring(1).split('&');
        for (var i = 0; i < pairs.length; i++) {
            var nameValue = pairs[i].split('=');
            nameValue[0] = decodeURI(nameValue[0]);
            nameValue[1] = decodeURI(nameValue[1]);
            obj[nameValue[0]] = nameValue[1];
        }
        return obj;
    }

    /*
     * expose public methods
     */
    return {
        init: init,
        showItem: showItem,
        closeItem: closeItem
    }

}();

