var software_$ = jQuery.noConflict(true);

software_$(document).ready(function() {
    // prepare the toolbar button, if it exists
    var toolbar_button = document.getElementById('software_fullscreen_toggle');
    
    // if the toolbar button exists, then initialize toolbar features
    if (toolbar_button) {
        // if the toolbar's display is set to none, then set that the toolbar is disabled
        if (document.getElementById('software_toolbar').style.display == 'none') {
            var toolbar_enabled = false;
            
        // else the toolbar's display is not set to none, so set that the toolbar is enabled
        } else {
            var toolbar_enabled = true;
        }
        
        // initialize variable for storing if the toolbar was originally enabled or disabled so that we can determine if the value has changed later
        var original_toolbar_enabled = toolbar_enabled;
        
        // add onclick event to toolbar button
        software_$(toolbar_button).click(function() {
            // if the toolbar is enabled, disable the toolbar
            if (toolbar_button.className == "up_button") {
                software_$("#software_toolbar").slideUp("fast");
                toolbar_button.className = "down_button";
                toolbar_button.title = 'Deactivate Fullscreen Mode';
                toolbar_enabled = false;
                
            // else the toolbar is disabled, so enable the toolbar
            } else if (toolbar_button.className == "down_button") {
                software_$("#software_toolbar").slideDown("fast");
                toolbar_button.className = "up_button";
                toolbar_button.title = 'Activate Fullscreen Mode';
                toolbar_enabled = true;
            }
        });
        
        // set toolbar height to the current height of the toolbar's iframe
        var toolbar_height = document.getElementById('software_toolbar').style.height.substring(0, document.getElementById('software_toolbar').style.height.lastIndexOf('p'));
        
        // set the original toolbar height to the starting height
        var original_toolbar_height = toolbar_height;
        
        // if the toolbar is expanded, then add onload event that will update the size of the toolbar
        if (toolbar_enabled == true) {
            document.getElementById('software_toolbar').onload = function() {
                // initialize variable for storing the height of the content in the toolbar
                var toolbar_content_height = '';
                
                // if the browser is webkit (e.g. Safari, Chrome), then use offsetHeight
                if (software_$.browser.safari) {
                    toolbar_content_height = document.getElementById('software_toolbar').contentWindow.document.body.offsetHeight;
                    
                // else the browser is another browser, so use scrollHeight
                } else {
                    toolbar_content_height = document.getElementById('software_toolbar').contentWindow.document.body.scrollHeight;
                }
                
                // update the height of the toolbar iframe so that it fits all of its content
                document.getElementById('software_toolbar').style.height = toolbar_content_height + 'px';
                
                // remember the new height
                toolbar_height = toolbar_content_height;
            };
        }
        
        // when the user browses away from this page, check to see if various properties need to be saved
        window.onbeforeunload = function() {
            // if the toolbar button exists and if any of the toolbar properties have changed, then save changes
            if ((original_toolbar_enabled != toolbar_enabled) || (original_toolbar_height != toolbar_height)) {
                // send an AJAX POST in order to save the toolbar properties in the session
                // async is set to false so that the request is sent before the browser window goes to the next page
                software_$.ajax({
                    type: 'POST',
                    url: '/' + software_directory + '/save_toolbar_properties.php',
                    data: 'enabled=' + toolbar_enabled + '&height=' + toolbar_height,
                    async: false
                });
            }
        }
    }
    
    // if the preview theme css toolbar is on the page, then update it's height
    if (document.getElementById("software_preview_design_code_toolbar")) {
        document.getElementById('software_preview_design_code_toolbar').onload = function() {
            // initialize variable for storing the height of the content in the toolbar
            var toolbar_content_height = '';
            
            // if the browser is webkit (e.g. Safari, Chrome), then use offsetHeight
            if (software_$.browser.safari) {
                toolbar_content_height = document.getElementById('software_preview_design_code_toolbar').contentWindow.document.body.offsetHeight;
                
            // else the browser is another browser, so use scrollHeight
            } else {
                toolbar_content_height = document.getElementById('software_preview_design_code_toolbar').contentWindow.document.body.scrollHeight;
            }
            
            // update the height of the toolbar iframe so that it fits all of its content
            document.getElementById('software_preview_design_code_toolbar').style.height = toolbar_content_height + 'px';
        };
    }
});

function change_states(country_element_id, state_element_id, preserve_state_value) {
    var country_element = document.getElementById(country_element_id);
    var state_element = document.getElementById(state_element_id);
    var new_states = new Array();
    var state_container_id = state_element_id + "_container";
    var state_element_value = state_element.value;

    var y = 0;
    // for all states in states array
    for (x = 0; x < states.length; x++) {
        // if this state is in the country that was selected, store this state
        if (states[x][2] == country_element.value) {
            new_states[y] = x;
            y++;
        }
    }

    // if there is at least one state for selected country, prepare selection drop-down field for state
    if (new_states.length > 0) {
        document.getElementById(state_container_id).innerHTML = '<select name="' + state_element_id + '" id="' + state_element_id + '" class="software_select"></select>';

        var new_state_element = document.getElementById(state_element_id);

        // set "-Select-" to be the first option of state selection drop-down field
        new_state_element.options[new_state_element.length] = new Option('-Select-', '');

        // loop through all states
        for (x = 0; x < new_states.length; x++) {
            new_state_element.options[new_state_element.length] = new Option(states[new_states[x]][0], states[new_states[x]][1]);
        }

    // else there is not a state for selected country, so prepare text field for state
    } else {
        document.getElementById(state_container_id).innerHTML = '<input type="text" name="' + state_element_id + '" id="' + state_element_id + '" class="software_input_text" />';
    }
    
    if ((preserve_state_value == true) && (state_element_value != '')) {
        document.getElementById(state_element_id).value = state_element_value;
    }
}

function change_quick_add_product_id(product_id)
{
    var selection_type;
    var default_quantity;
    var recipient_required;
    
    if (product_id) {
        selection_type = quick_add_products[product_id][0];
        default_quantity = quick_add_products[product_id][1];
        recipient_required = quick_add_products[product_id][2];        
    }
    
    // hide all quick add rows until we figure out which rows to show
    
    if (document.getElementById('quick_add_quantity_row')) {
        document.getElementById('quick_add_quantity_row').style.display = 'none';        
    }
    
    if (document.getElementById('quick_add_amount_row')) {
        document.getElementById('quick_add_amount_row').style.display = 'none';        
    }
    
    if (document.getElementById('quick_add_ship_to_row')) {
        document.getElementById('quick_add_ship_to_row').style.display = 'none';        
    }
    
    if (document.getElementById('quick_add_add_name_row')) {
        document.getElementById('quick_add_add_name_row').style.display = 'none';        
    }
    
    // if product has a quantity selection type, then prefill default quantity and show quantity row
    if (selection_type == 'quantity') {
        document.getElementById('quick_add_quantity').value = default_quantity;
        document.getElementById('quick_add_quantity_row').style.display = '';
    }
    
    // if product has a donation selection type, then show amount row
    if (selection_type == 'donation') {
        document.getElementById('quick_add_amount_row').style.display = '';
    }
    
    // if a recipient is required to be selected, then show ship to and add name rows
    if (recipient_required == true) {
        document.getElementById('quick_add_ship_to_row').style.display = '';
        document.getElementById('quick_add_add_name_row').style.display = '';
    }
}

function software_show_popup_menu(parent_element, position)
{
    parent_element.className = 'on';

    // loop through all nodes under li, in order to find a menu
    for (var i = 0; i < parent_element.childNodes.length; i++) {
        var node = parent_element.childNodes[i];
        
        // if node is a ul, then position menu and show menu
        if (node.nodeName == 'UL') {
            switch (position) {
                case 'Top':
                    node.style.left = '0';
                    node.style.top = '-' + node.offsetHeight + 'px';
                    break
                        
                case 'Bottom':
                    node.style.left = '0';
                    node.style.top = node.parentNode.offsetHeight + 'px';
                    break
                        
                case 'Left':
                    node.style.left = '-' + node.offsetWidth + 'px';
                    node.style.top = '0';
                    break;
                    
                case 'Right':
                    node.style.left = node.parentNode.offsetWidth + 'px';
                    node.style.top = '0';
                    break;
            }
            
            node.style.visibility = 'visible';
        }
    }
}

function software_hide_popup_menu(parent_element)
{
    parent_element.className = '';
    
    // loop through all nodes under li, in order to find a menu
    for (var i = 0; i < parent_element.childNodes.length; i++) {
        var node = parent_element.childNodes[i];
        
        // if node is a ul, then hide menu
        if (node.nodeName == 'UL') {
            node.style.visibility = 'hidden';
        }
    }
}

function software_photo_gallery_update_photo(photo_id)
{
    // If there is photo gallery information for the photo_id
    if (software_photo_gallery_photos[photo_id] === undefined) {
        photo_id = 0;
    }
    
    if (software_photo_gallery_photos[photo_id] !== undefined) {    
        if (software_photo_gallery_number_of_thumbnails > 0) {
            // If the specified photo_id is displayed in a thumbnail view higher than the one currently visible, slide it to the right.
            while (photo_id >= (software_photo_gallery_first_thumbnail_id + software_photo_gallery_number_of_thumbnails)) {
                software_photo_gallery_update_thumbnails('forward');
            }
            
            // If the specified photo_id is displayed in a thumbnail view lower than the one currently visible, slide it to the left.
            while (photo_id < software_photo_gallery_first_thumbnail_id) {
                software_photo_gallery_update_thumbnails('back');
            }
        }
        
        // If the main photo gallery image tag exists
        if (document.getElementById('software_photo_gallery_photo')) {
            // Set the image src to the specified photo_id
            document.getElementById('software_photo_gallery_photo').src = '/files/' + software_photo_gallery_photos[photo_id][0];
            
            // if there is an picnik edit button then rebuild it's href tag
            if (document.getElementById('software_edit_button_for_software_photo_gallery_photo')) {
                // parse the url for the ? and remove the php parameters so that we can rebuild them
                var image_url = document.getElementById('software_edit_button_for_software_photo_gallery_photo').href.substr(0, document.getElementById('software_edit_button_for_software_photo_gallery_photo').href.indexOf('?'));
                image_url += '?file_name=' + document.getElementById('software_photo_gallery_photo').src.substr(document.getElementById('software_photo_gallery_photo').src.lastIndexOf('/') + 1) + '&object_type=photo_gallery&object_id=0&send_to=' + software_send_to;
                
                document.getElementById('software_edit_button_for_software_photo_gallery_photo').href = image_url;
                document.getElementById('software_edit_button_for_software_photo_gallery_photo').title = 'Edit Image (' + document.getElementById('software_photo_gallery_photo').src.substr(document.getElementById('software_photo_gallery_photo').src.lastIndexOf('/') + 1) + ') with Picnik';
            }
            
            // If there is al ink around the main photo gallery photo, update its href to link to the new picture.
            if (document.getElementById('software_photo_gallery_photo_link')) {
                document.getElementById('software_photo_gallery_photo_link').setAttribute("href", "/files/" + software_photo_gallery_photos[photo_id][0]);
            }
            
            // If the caption area exists, update it with the specified photos caption.
            if (document.getElementById('software_photo_gallery_caption')) {
                document.getElementById('software_photo_gallery_caption').innerHTML = add_html_line_break_tags(prepare_content_for_html(software_photo_gallery_photos[photo_id][1]));
            }
            
            // store the previous selected thumbnail id in a variable, so that we can update its font weight.
            var software_photo_gallery_current_thumbnail_id = software_photo_gallery_current_photo_id - software_photo_gallery_first_thumbnail_id + 1;
            
            // If the first thumbnail exists, remove the class. (We could have moved to a thumbnail row that does not have the maximum amount of columns, so this could error)
            if (document.getElementById('software_photo_gallery_thumbnail_' + software_photo_gallery_current_thumbnail_id)) {            
                document.getElementById('software_photo_gallery_thumbnail_' + software_photo_gallery_current_thumbnail_id).className = 'thumbnail';
            }
            
            // If the first thumbnail label exists, remove the class. (We could have moved to a thumbnail row that does not have the maximum amount of columns, so this could error)
            if (document.getElementById('software_photo_gallery_thumbnail_label_' + software_photo_gallery_current_thumbnail_id)) {            
                document.getElementById('software_photo_gallery_thumbnail_label_' + software_photo_gallery_current_thumbnail_id).className = 'thumbnail_label';
            }
            
            // Update the global variable so software knows which photo is currently being shows (For the slideshow)
            software_photo_gallery_current_photo_id = photo_id;
            
            // store the selected thumbnail id in a variable, so that we can update its class to the active class
            var software_photo_gallery_current_thumbnail_id = photo_id - software_photo_gallery_first_thumbnail_id + 1;
            
            // If the selected thumbnail exists, assign it the active thumbnail class!
            if (document.getElementById('software_photo_gallery_thumbnail_' + software_photo_gallery_current_thumbnail_id)) {
                document.getElementById('software_photo_gallery_thumbnail_' + software_photo_gallery_current_thumbnail_id).className = 'current_thumbnail';
            }
            
            // If the selected thumbnail has a label, assign it the active thumbnail label class!
            if (document.getElementById('software_photo_gallery_thumbnail_label_' + software_photo_gallery_current_thumbnail_id)) {
                document.getElementById('software_photo_gallery_thumbnail_label_' + software_photo_gallery_current_thumbnail_id).className = 'current_thumbnail_label';
            }
        }
    }
}

function software_photo_gallery_update_thumbnails(direction)
{
    function update_onclick(thumbnail_id, photo_id)
    {
        document.getElementById('software_photo_gallery_thumbnail_' + thumbnail_id).onclick = function() { software_photo_gallery_update_photo(photo_id); };
    }

    switch (direction) {
        case 'back':
            // If this is not the first thumbnail view, allow it to move backwards
            if (software_photo_gallery_first_thumbnail_id != 0) {
                software_photo_gallery_first_thumbnail_id = software_photo_gallery_first_thumbnail_id - software_photo_gallery_number_of_thumbnails;
                
                // If we traveled into the negatives, set it to 0 instead.
                if (software_photo_gallery_first_thumbnail_id < 0) {
                    software_photo_gallery_first_thumbnail_id = 0;
                }
                
                // For each thumbnail
                for (var i = 0; i < software_photo_gallery_number_of_thumbnails; i++) {
                    var current_image_index = software_photo_gallery_first_thumbnail_id + i;
                    
                    // If the thumbnail exists
                    if (document.getElementById('software_photo_gallery_thumbnail_' + (i + 1))) {
                        // If the thumbnail photo does not exists
                        if (software_photo_gallery_photos[current_image_index] === undefined) {
                            // Hide the thumbnails table cell.
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).parentNode.style.display = 'none';
                            document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).parentNode.style.display = 'none';
                            // Remove the previous photo, onclick, and label if any.
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src = '';
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).onclick = '';
                            document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).innerHTML = '';
                            
                        // Else, there is a photo for the current thumbnail
                        } else {
                            // Update the thumbnails img src, label and onclick
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src = '/files/' + software_photo_gallery_photos[current_image_index][0];
                            document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).innerHTML = (current_image_index + 1);
                            update_onclick(i + 1, current_image_index);
                            
                            // If the current thumbnail is the current main photo gallery image, apply the active class
                            if (document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src == document.getElementById('software_photo_gallery_photo').src) {
                                document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).className = 'current_thumbnail_label';
                            	document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).className = 'current_thumbnail';
                            // Else, remove the active class just in case there is some previously selected image with the active class applied.
                            } else {
                                document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).className = 'thumbnail_label';
                                document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).className = 'thumbnail';
                            }
                            
                            // Display the thumbnail table cell.
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).parentNode.style.display = '';
                            document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).parentNode.style.display = '';
                        }
                        
                        // if there is an picnik edit button rebuild the href tags
                        if (document.getElementById('software_edit_button_for_software_photo_gallery_photo')) {
                            // parse the url for the ? and remove the php parameters so that we can rebuild them
                            var image_url = document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href.substr(0, document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href.indexOf('?'));
                            image_url += '?file_name=' + document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.substr(document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.lastIndexOf('/') + 1) + '&object_type=photo_gallery&object_id=0&send_to=' + software_send_to;
                            
                            document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href = image_url;
                            document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).title = 'Edit Image (' + document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.substr(document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.lastIndexOf('/') + 1) + ') with Picnik';
                        }
                    }
                }
            }
            break;
                
        case 'forward':
            // If there are more photos in the photo array, update the first thumbnail id.
            if (software_photo_gallery_photos[software_photo_gallery_first_thumbnail_id + software_photo_gallery_number_of_thumbnails] !== undefined) {
                software_photo_gallery_first_thumbnail_id = software_photo_gallery_first_thumbnail_id + software_photo_gallery_number_of_thumbnails;
            }
            
            // For each thumbnail
            for (var i = 0; i < software_photo_gallery_number_of_thumbnails; i++) {
                var current_image_index = software_photo_gallery_first_thumbnail_id + i;
                
                // If the thumbnail container exists
                if (document.getElementById('software_photo_gallery_thumbnail_' + (i + 1))) {
                    // If there is not a photo for this thumbnail
                    if (software_photo_gallery_photos[current_image_index] === undefined) {
                        // Hide its container, remove its photo, its label and its onclick event
                        document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).parentNode.style.display = 'none';
                        document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).parentNode.style.display = 'none';
                        document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src = '';
                        document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).onclick = '';
                        document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).innerHTML = '';
                    
                    // Else, there was a photo that we can use
                    } else {
                        // Update its photo and label
                        document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src = '/files/' + software_photo_gallery_photos[current_image_index][0];
                        document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).innerHTML = (current_image_index + 1);
                        
                        // Assign it an onclick.
                        update_onclick(i + 1, current_image_index);
                        
                        // If the thumbnail image is the same as the main photo gallery photo, apply the active class
                        if (document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src == document.getElementById('software_photo_gallery_photo').src) {
							document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).className = 'current_thumbnail_label';
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).className = 'current_thumbnail';
                        // Else, remove the active class
                        } else {
                            document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).className = 'thumbnail_label';
                            document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).className = 'thumbnail';
                        }
                        
                        // Display the thumbnail container
                        document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).parentNode.style.display = '';
                        document.getElementById('software_photo_gallery_thumbnail_label_' + (i + 1)).parentNode.style.display = '';
                    }
                    
                    // if there is an picnik edit button rebuild the href tags
                    if (document.getElementById('software_edit_button_for_software_photo_gallery_photo')) {
                        // parse the url for the ? and remove the php parameters so that we can rebuild them
                        var image_url = document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href.substr(0, document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href.indexOf('?'));
                        image_url += '?file_name=' + document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.substr(document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.lastIndexOf('/') + 1) + '&object_type=photo_gallery&object_id=0&send_to=' + software_send_to;
                        
                        document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).href = image_url;
                        document.getElementById('software_edit_button_for_software_photo_gallery_thumbnail_' + (i + 1)).title = 'Edit Image (' + document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.substr(document.getElementById('software_photo_gallery_thumbnail_' + (i + 1)).src.lastIndexOf('/') + 1) + ') with Picnik';
                    }
                }
            }
            
            break;
    }
}

function software_photo_gallery_start_slideshow()
{
    // If the slideshow is not currently enabled.
    if (software_photo_gallery_slideshow === false) {
        // Start the slideshow
        window.setTimeout("software_photo_gallery_update_slideshow()", software_photo_gallery_slideshow_interval);
        
        // Switch the font weight
        document.getElementById('software_photo_gallery_slideshow_on').className = 'active';
        document.getElementById('software_photo_gallery_slideshow_off').className = '';
        
        // Set the global variable so we now know that the slideshow is enabled.
        software_photo_gallery_slideshow = true;
        
    }
}

function software_photo_gallery_stop_slideshow()
{
    // Disable the slideshow so the photo will stop changing.
    software_photo_gallery_slideshow = false;
    
    // Switch the font weight.
    document.getElementById('software_photo_gallery_slideshow_on').className = '';
    document.getElementById('software_photo_gallery_slideshow_off').className = 'active';
}

function software_photo_gallery_update_slideshow()
{
    // If the slideshow is enabled.
    if (software_photo_gallery_slideshow === true) {
        var current_photo_id = software_photo_gallery_current_photo_id + 1;
        
        // Update the current photo gallery main photo!
        software_photo_gallery_update_photo(current_photo_id);
        
        // If there is photo gallery information for the photo, then setup recursion to update slideshow
        if (software_photo_gallery_photos[current_photo_id] != undefined) {
            window.setTimeout("software_photo_gallery_update_slideshow()", software_photo_gallery_slideshow_interval);
        
        // else stop slideshow
        } else {
            software_photo_gallery_stop_slideshow();
        }
    }
}

function software_update_accordion_menu(menu_item_id, parent_menu_item_id, menu_id) {
    
    // set open menu item id to the global open menu item id
    open_menu_item_id = eval("software_menu_"+menu_id+"_open_menu_item_id");
    
    // get display status of menu item
    var menu_item_display_status = document.getElementById("software_menu_item_" + menu_item_id).getElementsByTagName("ul")[0].style.display;
    
    // If the open menu item is not zero and it is not the parent menu item
    if ((open_menu_item_id != 0) && (open_menu_item_id != parent_menu_item_id)) {
        
        // Close the open menu item
        software_hide_accordion_menu(open_menu_item_id, parent_menu_item_id, menu_id);
    }
    
    // If the current menu item was not open
    if (menu_item_display_status != "block") {
        
        // then slide down the current menu item
        software_$(document.getElementById("software_menu_item_" + menu_item_id).getElementsByTagName("ul")[0]).slideDown("fast");
        
        // update open menu item id
        eval("software_menu_"+menu_id+"_open_menu_item_id = " + menu_item_id);
    }
}

function software_hide_accordion_menu(menu_item_id, stop_before_menu_item_id, menu_id) {
    
    // If this menu item id is equal to the stop before menu item id
    if (menu_item_id == stop_before_menu_item_id) {
        
        // set open menu item id to menu item id
        eval("software_menu_"+menu_id+"_open_menu_item_id = " + menu_item_id);
        
        // then return out of function
        return;
        
    // else if we have not reached the stop before menu item id
    } else {
        
        // slide up menu item
        software_$(document.getElementById("software_menu_item_" + menu_item_id).getElementsByTagName("ul")[0]).slideUp("fast");

        // if the direct parent to the li is the software menu ul
        if ((document.getElementById("software_menu_item_" + menu_item_id).parentNode.className) && 
            (document.getElementById("software_menu_item_" + menu_item_id).parentNode.className == "software_menu")) {
            
            // set open menu item id to 0
            eval("software_menu_"+menu_id+"_open_menu_item_id = 0");
            
            // return
            return;
            
        // else continue
        } else {
            
            // get menu item's parent menu item id
            parent_menu_item_id = document.getElementById("software_menu_item_" + menu_item_id).parentNode.parentNode.id;
            
            // remove software_menu_item from the id
            parent_menu_item_id = parent_menu_item_id.replace(/software_menu_item_/, "");
            
            // call this function again to close the parent menu item
            software_hide_accordion_menu(parent_menu_item_id, stop_before_menu_item_id, menu_id);
        }
    }
}

// this function initializes a dynamic ad region and starts the animation
function software_initialize_dynamic_ad_region(ad_region_name, transition_type, transition_duration, slideshow, slideshow_interval)
{
    // when the document is ready, then continue
    software_$(document).ready(function () {
        var ad_elements = software_$('#software_ad_region_' + ad_region_name + ' .ads > div');
        var ads_element = software_$('#software_ad_region_' + ad_region_name + ' .ads');
        
        // get the ads container element and apply the hidden overflow in order to remove scrollbars
        var ads_container_element = software_$('#software_ad_region_' + ad_region_name + ' .ads_container').css('overflow', 'hidden');
        
        // get the menu item link element that has this target, select the menu item and it's corresponding ad
        function trigger(data) {
            var menu_item_link_element = software_$('#software_ad_region_' + ad_region_name + ' .menu').find('a[href$="' + data.id + '"]').get(0);
            
            // if this is a slide transition then call the function that updates it's menu items
            if (transition_type == 'slide') {
                update_current_ad_menu_item(menu_item_link_element);
                
            // else this is a fade transition type, so fade the content
            } else {
                fade_ads(menu_item_link_element, ad_region_name, transition_duration);
            }
        }
        
        // if the transition type is set to slide, prepare and initialize the slide effect
        if (transition_type == 'slide') {
            // float the ads so they are in a horizontal line
            ad_elements.css({
                'float' : 'left',
                'position' : 'relative' // IE fix to ensure overflow is hidden
            });
            
            // calculate a new width for the container (so it holds all ads)
            ads_element.css('width', ad_elements[0].offsetWidth * ad_elements.length);
            
            // add click event handler to menu items
            software_$('#software_ad_region_' + ad_region_name + ' .menu').find('a').click(function(){update_current_ad_menu_item(this)});
            
            // if there is a bookmark in the location, then select the corresponding menu item
            if (window.location.hash) {
                trigger({ id : window.location.hash.substr(1) });
                
            // else there is not a bookmark in the location, so select the first menu item
            } else {
                software_$('#software_ad_region_' + ad_region_name + ' ul.menu a:first').click();
            }
            
            // prepare the offset which is based on the padding of an element
            var offset = parseInt(ads_element.css('paddingTop') || 0) * -1;
            
            // prepare the scroll options for the scroll plugin
            var scrollOptions = {
                // set the element that has the overflow
                target: ads_container_element,
                
                // set the container for the ads
                items: ad_elements,
                
                // set where the menu is located
                navigation: '.menu a',
                
                // set that the scrolling should only work horizontally
                axis: 'x',
                
                // set callback
                onAfter: trigger,
                
                // set offset based on padding
                offset: offset,

                // set the speed of the scroll effect
                duration: transition_duration,
                
                // easing - can be used with the easing plugin: 
                // http://gsgd.co.uk/sandbox/jquery/easing/
                easing: 'swing'
            };
            
            // initialize the serialScroll plugin that handles the scrolling effect and allows the slideshow effect to work
            software_$('#software_ad_region_' + ad_region_name).serialScroll(scrollOptions);
        
        // else prepare and initialize the the fade effect
        } else {
            // place the ads menu above the ads in the stack
            software_$('#software_ad_region_' + ad_region_name + ' .menu').css({'z-index' : '2'});
            
            // update the ads CSS to stack them on top of each other, put them at the bottom of the stack, and hide them all
            software_$('#software_ad_region_' + ad_region_name + ' .ads_container .ad').css({
                'position' : 'absolute',
                'top' : '0px',
                'left' : '0px',
                'z-index' : '0',
                'float' : 'none',
                'filter:alpha' : '(opacity=0)',
                '-moz-opacity' : '0',
                '-khtml-opacity' : '0',
                'opacity' : '0'
            });
            
            // add click event handler to menu items, then onclick prepare the menu items and call the fade ads function
            software_$('#software_ad_region_' + ad_region_name + ' .menu').find('a').click(function(mouse_event){
                // prevent the link from reloading the page
                mouse_event.preventDefault();
                
                // call the fade function
                fade_ads(this, ad_region_name, transition_duration);
            });
            
            // if there is a bookmark in the location, then unhide it's ad and select the corresponding menu item
            if (window.location.hash) {
                // set the corresponding ad to be visable
                software_$('#software_ad_region_' + ad_region_name + ' .ads_container #' + window.location.hash.substr(1)).css({
                    'filter:alpha' : '(opacity=1)',
                    '-moz-opacity' : '1',
                    '-khtml-opacity' : '1',
                    'opacity' : '1'
                });
                
                // trigger the change to update the menu
                trigger({ id : window.location.hash.substr(1) });
                
            // else there is not a bookmark in the location, so unhide the first ad and select the first menu item
            } else {
                // set the first ad to be visable
                software_$(software_$('#software_ad_region_' + ad_region_name + ' .ads_container .ad')[0]).css({
                    'filter:alpha' : '(opacity=1)',
                    '-moz-opacity' : '1',
                    '-khtml-opacity' : '1',
                    'opacity' : '1'
                });
                
                // trigger the change to update the menu
                trigger({ id : software_$('#software_ad_region_' + ad_region_name + ' ul.menu a:first')[0].href.substr(software_$('#software_ad_region_' + ad_region_name + ' ul.menu a:first')[0].href.lastIndexOf('#') + 1) });
            }
        }
        
        // if slideshow is enabled for this ad region, then initialize slideshow
        if (slideshow == true) {
            // start the slideshow with the correct interval
            var cycle_timer = setInterval(function () {
                
                // if this transition type is a slide, then trigger the slide
                if (transition_type == 'slide') {
                    ads_container_element.trigger('next');
                
                // else this is a fade so trigger the next fade
                } else {
                    // pass the next ad into the trigger function
                    trigger({ id : software_$(software_$('#software_ad_region_' + ad_region_name + ' ul.menu a.current')[0].parentNode).next('li')[0].firstChild.href.substr(software_$(software_$('#software_ad_region_' + ad_region_name + ' ul.menu a.current')[0].parentNode).next('li')[0].firstChild.href.lastIndexOf('#') + 1) });
                }
               
                // if we have reached the end of the slideshow, then stop slideshow
                if (software_$('#software_ad_region_' + ad_region_name + ' ul.menu li:last-child a').attr('class') == 'current') {
                    clearInterval(cycle_timer);
                   
                    // if this is the fade transition type, then send the slideshow back to the first ad after the set amount of time has passed
                    if (transition_type == 'fade') {
                        setTimeout("fade_ads('', '" + ad_region_name + "', " + transition_duration + ");", slideshow_interval * 1000);
                    }
                }
               
            }, slideshow_interval * 1000);
            
            // set some trigger elements to stop the slideshow
            var stop_triggers = software_$('#software_ad_region_' + ad_region_name + ' .menu').find('a') // menu items
                .add('#software_ad_region_' + ad_region_name + ' .ads_container') // ads container
            
            // create a function to stop the slideshow
            function stop_slideshow() {
                // remove the stop triggers
                stop_triggers.unbind('click.cycle');
                
                // stop the slideshow
                clearInterval(cycle_timer);
            }
            
            // bind the stop slideshow function to the stop triggers
            stop_triggers.bind('click.cycle', stop_slideshow);
        }
    });
}

// this function fades one ad in and one ad out
function fade_ads(selected_menu_item, ad_region_name, transition_duration) {
    // if there is not a selected menu item, then set it to the first menu item
    if ((!selected_menu_item) || (selected_menu_item == '')) {
        selected_menu_item = software_$('#software_ad_region_' + ad_region_name + ' ul.menu a:first')[0];
    }
    
    // get the selected ad id
    var selected_ad_id = selected_menu_item.href.substr(selected_menu_item.href.lastIndexOf('#') + 1);
    
    var current_ad_id = 0;
    
    // if there is a current menu item, then get the current ad's id
    if (software_$('#software_ad_region_' + ad_region_name + ' .menu a.current')[0]) {
        current_ad_id = software_$('#software_ad_region_' + ad_region_name + ' .menu a.current')[0].href.substr(software_$('#software_ad_region_' + ad_region_name + ' .menu a.current')[0].href.lastIndexOf('#') + 1);
    }
    
    // update the current menu item
    update_current_ad_menu_item(selected_menu_item);
    
    // if the transition duration is 0, then default it to one second
    if (transition_duration == 0) {
        transition_duration = 1000;
    }
    
    // fade in the new ad, and after the fade is complete set it's z-index to 1 so it's on top of the stack
    software_$(software_$('#software_ad_region_' + ad_region_name + ' .ads_container #' + selected_ad_id)[0]).animate({
        opacity: 1
    }, transition_duration, function () {
        software_$(software_$('#software_ad_region_' + ad_region_name + ' .ads_container #' + selected_ad_id)[0]).css('z-index', '1');
    });
    
    // fade out the old ad, and after the fade is complete set it's z-index to 0 so that it is under the current ad
    software_$(software_$('#software_ad_region_' + ad_region_name + ' .ads_container #' + current_ad_id)[0]).animate({
        opacity: 0
    }, transition_duration, function () {
        software_$(software_$('#software_ad_region_' + ad_region_name + ' .ads_container #' + current_ad_id)[0]).css('z-index', '0');
    });
}

// this function updates the current menu item
function update_current_ad_menu_item(object)
{
    software_$(object)
        .parents('ul:first')
            .find('a')
                .removeClass('current')
            .end()
        .end()
        .addClass('current');
}

function prepare_content_for_html(content)
{
    var chars = new Array ('&','à','á','â','ã','ä','å','æ','ç','è','é',
                         'ê','ë','ì','í','î','ï','ð','ñ','ò','ó','ô',
                         'õ','ö','ø','ù','ú','û','ü','ý','þ','ÿ','À',
                         'Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë',
                         'Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö',
                         'Ø','Ù','Ú','Û','Ü','Ý','Þ','€','\"','ß','<',
                         '>','¢','£','¤','¥','¦','§','¨','©','ª','«',
                         '¬','­','®','¯','°','±','²','³','´','µ','¶',
                         '·','¸','¹','º','»','¼','½','¾');

    var entities = new Array ('amp','agrave','aacute','acirc','atilde','auml','aring',
                            'aelig','ccedil','egrave','eacute','ecirc','euml','igrave',
                            'iacute','icirc','iuml','eth','ntilde','ograve','oacute',
                            'ocirc','otilde','ouml','oslash','ugrave','uacute','ucirc',
                            'uuml','yacute','thorn','yuml','Agrave','Aacute','Acirc',
                            'Atilde','Auml','Aring','AElig','Ccedil','Egrave','Eacute',
                            'Ecirc','Euml','Igrave','Iacute','Icirc','Iuml','ETH','Ntilde',
                            'Ograve','Oacute','Ocirc','Otilde','Ouml','Oslash','Ugrave',
                            'Uacute','Ucirc','Uuml','Yacute','THORN','euro','quot','szlig',
                            'lt','gt','cent','pound','curren','yen','brvbar','sect','uml',
                            'copy','ordf','laquo','not','shy','reg','macr','deg','plusmn',
                            'sup2','sup3','acute','micro','para','middot','cedil','sup1',
                            'ordm','raquo','frac14','frac12','frac34');

    for (var i = 0; i < chars.length; i++) {
        myRegExp = new RegExp();
        myRegExp.compile(chars[i],'g');
        content = content.replace (myRegExp, '&' + entities[i] + ';');
    }

    return content;
}

function add_html_line_break_tags(content)
{
    return content.replace("\n", "<br />\n");
}

// this is the timer used for the picnik button animation
var edit_image_button_timer = Array;

function software_show_or_hide_image_edit_button(image_id, event) 
{
    clearTimeout(edit_image_button_timer[image_id]);
    
    image = document.getElementById(image_id);
    
    // if the edit button is hidden then update it's position and show it
    if (event.type == 'mouseover') {
        // if this is not a photo gallery page, or if it is a photo gallery page and if this is the main photo, 
        // then the position of the image and update it's position
        if ((!document.getElementById("software_photo_gallery_photo")) || ((document.getElementById("software_photo_gallery_photo")) && (image.id == "software_photo_gallery_photo"))) {
            // if the images parent's position is not relative then set the position to be relative,
            // and get the position of the parent and add it to the relative image position to get the screen position
            if (image.offsetParent.style.position != 'relative') {
                // get the orginal position styling for the object
                var orignal_position_styling = image.offsetParent.style.position;
                
                // set it's position to be relative
                image.offsetParent.style.position = 'relative';
                
                // get the image's dimensions
                var image_left_position = image.offsetParent.offsetLeft + image.offsetLeft;
                var image_top_position = image.offsetParent.offsetTop + image.offsetTop;
                
                // switch the position back to what it was originally
                image.offsetParent.style.position = orignal_position_styling;
                
            // else the parent is relative so we do not need to get the parent's position
            } else {
                var image_left_position = image.offsetLeft;
                var image_top_position = image.offsetTop;
            }
            
            // update button position
            document.getElementById("software_edit_button_for_" + image_id).style.left = image_left_position + "px";
            document.getElementById("software_edit_button_for_" + image_id).style.top = image_top_position + "px";
        }
        
        // show the image
        document.getElementById("software_edit_button_for_" + image_id).style.display = "block";
        
    // else if the event was a mouseout, then slide up the button to hide it.
    } else if (event.type == 'mouseout') {
        edit_image_button_timer[image_id] = setTimeout('software_$(document.getElementById("software_edit_button_for_' + image_id + '")).slideUp("fast");', 250);
    }
}

function software_show_form_view_directory_summary(summary)
{
    // do different things based on which summary was selected
    switch (summary) {
        case 'most_recent':
            // show and hide summary tables
            document.getElementById('software_form_view_directory_summary_table_most_viewed').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_active').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_recent').style.display = '';
            
            // update font weight for summary links
            document.getElementById('software_form_view_directory_summary_link_most_viewed').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_active').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_recent').style.fontWeight = 'bold';
            
            break
                
        case 'most_viewed':
            // show and hide summary tables
            document.getElementById('software_form_view_directory_summary_table_most_recent').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_active').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_viewed').style.display = '';

            // update font weight for summary links
            document.getElementById('software_form_view_directory_summary_link_most_recent').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_active').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_viewed').style.fontWeight = 'bold';
            
            break
                
        case 'most_active':
            // show and hide summary tables
            document.getElementById('software_form_view_directory_summary_table_most_recent').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_viewed').style.display = 'none';
            document.getElementById('software_form_view_directory_summary_table_most_active').style.display = '';
            
            // update font weight for summary links
            document.getElementById('software_form_view_directory_summary_link_most_recent').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_viewed').style.fontWeight = '';
            document.getElementById('software_form_view_directory_summary_link_most_active').style.fontWeight = 'bold';
            
            break;
    }
}