
/******************************************************************************/
/**                                                                          **/
/**                              Category menu                               **/
/**                                                                          **/

(function($) {

//------------------------------------------------------------------------------
// constructor (must be before the public functions) ---------------------------
//------------------------------------------------------------------------------

jQuery.categoryMenu = {};

//------------------------------------------------------------------------------
// public functions ------------------------------------------------------------
//------------------------------------------------------------------------------
/**
 * @param trigger DOM element The element that triggers the event. Used to
 *        know if it must be opened the category panel of the search panel
 *        or the item form.
 *
 * @uses $.globalFunctions.dialogOpen()
 * @uses $.globalFunctions.getAjaxUrl()
 * @uses $.categoryMenu.loaded()
 */
jQuery.categoryMenu.selectCategoriesEvent = function(trigger) {

    var $trigger = $(trigger);

//    $trigger.siblings('div.selectedActivities').addClass('categoryMenuCaller');
    
    var ajaxUrl = 'categoryMenuSearchPanel';
    var buttons = $.extend(
            {},
            $.configuration.dialog.buttons.categoryMenuAccept,
            $.configuration.dialog.buttons.categoryMenuCancel
    );
    if ($trigger.is('.itemForm')) {
        ajaxUrl = 'categoryMenuItemForm';
        buttons = $.configuration.dialog.buttons.categoryMenuCancel;
    }

    var settings = {
        scrollToTop: false, // a scroll to top action is bound to the close event
        title: $.messages.dialog.titles.categoryPanel,
        message: '',
        buttons: buttons,
        resizable: false,
        width: 930,
        minHeight: 500,
        close: $.configuration.dialog.events.closeCategoryMenuTasks
    };

    $.globalFunctions.dialogOpen(settings);
    
    // Discussion: Is it efficient to get the activities menu everytime,
    // or is it better to load it only the first time the dialog is
    // opened?
    // I think it is not worth to implement an algorithm to avoid
    // multiple loads of the activity menu dialog, because there is
    // only one shared dialog box in the system, which is used for every
    // purpose, and its content may have changed the next time the
    // activity menu is requested. Besides, the activity menu is supposed
    // to be opened only once per pageview.
    $('#dialog').find('.content').load(
        $.globalFunctions.getAjaxUrl(ajaxUrl),
        $.categoryMenu.loaded
    );
};

//------------------------------------------------------------------------------

//jQuery.activitiesMenu.loadedItemForm = function() {
jQuery.categoryMenu.loaded = function() {

    $.globalFunctions.setDialogPositionAndFocus($('#dialog'));
    $('.overlay').height($(document).height() + 15);

    // the li elements that content a category group (.subpanel) must not
    // launch the event, the li elements within it must launch the event
    $('.itemFormBody .categoryPanel .categoryGroup li:not(.subpanel)').click(function() {
        var $this = $(this);
        var $categoryGroup = $this.parents('.categoryGroup:first');
        var categoryGroupId = $categoryGroup.attr('categoryGroupId');
        var categoryId = $this.attr('categoryId');
        var category = $.trim($categoryGroup.find('h4:first').text())
                     + $.configuration.breadcrumbSeparator + $.trim($this.text());
        $('#category')
            .attr({
                categoryId: categoryId,
                categoryGroupId: categoryGroupId
            })
            .val(category)
            .show();

//        $.categoryMenu.toggleFeaturesAndAdTypes(categoryGroupId, categoryId);
//        $.categoryMenu.toggleFeaturesAndAdTypes({
        $.categoryMenu.adjustFormToCategory({
            containerElementClass: 'itemForm',
            categoryGroupId: categoryGroupId,
            categoryId: categoryId
        });

        $('.selectCategory button').hide();
//        $.categoryMenu.closeCategoryMenuTasks();
//
//        $.globalFunctions.dialogClose();

        $.categoryMenu.close();
    });

    // BUG: If the "input" selector is not placed before the ":checkbox" filter,
    //      IE crashes.
    $('.categoryPanel input:checkbox').change(function() {

        var $this = $(this);

        var multigroup = false;

        // it is checked if there are selected categories in other groups only
        // if the checkbox is checked, and not when it is unchecked
        if ($this.is(':checked')) {
            multigroup = checkMultigroup($this);
        }

        if (multigroup) {

            var settings = {
                dialogBoxId: 'multiGroupSelection',
                scrollToTop: true,
                title: $.messages.dialog.titles.multiGroupSelection,
                message: $.messages.dialog.messages.multiGroupSelection,
                buttons: $.configuration.dialog.buttons.ok,
                width: 300
            };

            $.globalFunctions.dialogOpen(settings);

            $this.removeAttr('checked');
        }
        else {
            // the label is set to bold when the checkbox is checked
            $this.parent().toggleClass('selectedCategory');
        }
    });

    // the previously selected categories are checked in the category panel
    $('.selectedCategories li').each(function() {
        $('.categoryPanel #' + $(this).attr('checkboxId')).click().change();
    });

    // the event of the clean button is set
    $('.categoryPanel .clean')
        .click(function() {
            // BUG: If the "input" selector is not placed before the ":checkbox"
            //      filter, IE crashes.
            $('.categoryPanel input:checkbox:checked').removeAttr('checked').change();
        })
        .hover($.globalFunctions.displayTooltip, $.globalFunctions.removeTooltip);
};

//------------------------------------------------------------------------------

//jQuery.categoryMenu.toggleFeaturesAndAdTypesSearchPanel = function(categoryGroupId) {
//
//    var $adType = $('.searchPanel .adType');
//    var $adTypeSelect = $adType.find('select');
//
//    if ( ! categoryGroupId) {
//        $('.searchFeatures').hide();
//    }
//    else {
//        $('.searchPanel .features:not(.' + categoryGroupId + ')').hide();
//        $('.searchPanel .features.' + categoryGroupId).slideDown(1000);
//    }
//
//    // every element must be hidden except the first one, which is blank and
//    // has no class attribute
//    $adTypeSelect.find('option[class]').hide();
//
//    // categoryGroupId 17 -> Friends and dating
//    // categoryId 270 -> Blogs and opinion
//    // categoryId 275 -> Language and other skills swap
////    if ((categoryGroupId == 17) || (categoryId == 270) || (categoryId == 275)) {
//    if ((categoryGroupId == 17)) {
//        $adType.hide();
//    }
//    else {
//        // the category group ids between 7 and 15 are the children of the
//        // trading category group (6). They all have the same ad types
//        if ((categoryGroupId >= 7) && (categoryGroupId <= 15)) {
//            categoryGroupId = 6;
//        }
//        $adType.show().find('option.' + categoryGroupId).show();
//    }
//
//    if ($adTypeSelect.find(':checked').is(':hidden')) {
//        $adTypeSelect.val('');
//    }
//
//};

//------------------------------------------------------------------------------

//jQuery.categoryMenu.toggleFeaturesAndAdTypes = function(categoryGroupId, categoryId) {
//jQuery.categoryMenu.toggleFeaturesAndAdTypes = function(options) {
jQuery.categoryMenu.adjustFormToCategory = function(options) {
//$('body').prepend($('.' + options.containerElementClass));
//$('body').prepend($('.' + options.containerElementClass + ' .adType select'));
//$('body').prepend($('.' + options.containerElementClass + ' .adType select:first'));
//$('body').prepend($('.' + options.containerElementClass + ' .adType select:last'));
    var $features = $('.' + options.containerElementClass + ' .features');
//    var $adType = $('.' + options.containerElementClass + ' .adType');
    // NOTE: The ad type select is called adType in the item form and cmbAdTypes
    // in the search panel
    var $adType = $('.' + options.containerElementClass + ' .adType select:first');
//    $('body').prepend($adType);
//    $adType.parent().append($adType);
//    $adType.parent();
//    var $adTypeSelect = $adType.find('select');
//    var $adTypeSelect = $adType.find('#adType');
//    var $adType = $('#adType');
    var $adTypeHidden = $('#adTypeHidden');
    var categoryGroupId = options.categoryGroupId;
    var categoryId = options.categoryId;

    // every element in the ad type select must be hidden except the first one,
    // which is blank and has no class attribute
//    $adType.find('option[class]').hide();
//
//    if ( ! categoryGroupId) {
//        $features.hide();
//    }
//    else {
//        $features.filter(':not(.categoryGroup' + categoryGroupId + ')').hide();
//        $features.filter('.categoryGroup' + categoryGroupId).slideDown(1000);
//        // next statement fails if categoryGroupId is null
////        $adType.find('option.' + categoryGroupId).show();
//        $adType.find('option.' + categoryGroupId).show();
//    }
//
//    // if the selected ad type is now hidden, the ad type drop down list must
//    // be cleared, and its change event launched. This event may show the
//    // price input box, so it must be run before the price input box is shown
//    // or hiden by the category group adjustment (below)
//    if ($adType.find(':selected').is(':hidden')) {
//        $adType.val('').change();
//    }


//    if ( ( ! categoryGroupId) && (options.containerElementClass == 'searchPanel')) {
//        // if there is no selected category, hence no category group, every
//        // ad type must be shown, to make possible to filter by them
//        $adTypeSelect.find('option').show();
//    }

    // NOTE: Select options can be hidden only in Firefox, so the not
    //       needed options of a select must be removed, and the required
    //       ones are taken from a hidden select, which contains all the
    //       options.

    // if there is no options or just one option (the empty one), the select
    // is empty and its value is not stored
    if ($adType.find('option').length > 1) {
        $adTypeHidden.val($adType.sanitizedValue());
    }

    if ( ! categoryGroupId) {
        $adType.html('').addClass('disabled').change();
        $features.hide();
    }
    else {
        // the category group ids between 7 and 15 are the children of the
        // trading category group 6. They all have the same ad types
        if ((categoryGroupId >= 7) && (categoryGroupId <= 15)) {
            categoryGroupId = 6;
        }
        
        $features.filter(':not(.categoryGroup' + categoryGroupId + ')').hide();
        $features.filter('.categoryGroup' + categoryGroupId).slideDown(1000);
//$adType.val('3');
        // the first option is the blank one and must be included
        // NOTE: Next statement fails if categoryGroupId is null
        $adType.html($adTypeHidden.find('option:first, option.' + categoryGroupId).clone());
        // when the ad type drop down list is changed, its change event must
        // be launched, so that the price input box is shown or hidden. This
        // event must be run before the price input box is shown or hiden by
        // the category group adjustment (below)
//$('body').prepend($adTypeHidden.sanitizedValue() + ' - XXXXXXXXXXX');
//$('body').prepend($adType.sanitizedValue() + ' - XXXXXXXXXXX');
//$('body').prepend($adType.html());
//    $adType.parent().append($adType);

        // BUG: If the ad type select is not set in the DOM before assigning its
        //      value, IE6 fails. If the select is appended to the parent element,
        //      the layout breaks.
        if ($.browser.msie && ($.browser.version < 7)) {
            $adType.parent().find('label').after($adType);
        }
//    $adType.parent().append($adType).append($adTypeHidden);
//    $adType.parent().html($adType.parent().html());
//    $adType.html($adType.html());
//    $adType.show();
//$('body').prepend($adType);
//        $adType.val('1');
//        $adType.val('Vendo');
//        $('#adType').val('3');
        $adType.val($adTypeHidden.sanitizedValue()).removeClass('disabled').change();
//        $adType.val($adTypeHidden.sanitizedValue());
//        $adType.removeClass('disabled').change();
    }

//    $('#adType').empty();
//    $('#adType').html($('#adTypeHidden option.' + categoryGroupId).clone());
//    $adType.html($adTypeHidden.find('option:first').add('#adTypeHidden option.' + categoryGroupId).clone());

    // categoryGroupId 17 -> Friends and dating
    // categoryId 270 -> Blogs and opinion
    // categoryId 275 -> Language and other skills swap
    if ((categoryGroupId == 17) || (categoryId == 270) || (categoryId == 275)) {
        $adType.parent().hide();
        $('.' + options.containerElementClass + ' .price').hide();
        // previous values must be removed, so they are not retrieved from
        // the form and stored in the database. If it is an update, the
        // values will be so removed from the database
//        $adType.val('').hide();
//        $('.' + options.containerElementClass + ' .price').val('').hide();
    }
    else {
//        $adType.show().find('option.' + categoryGroupId).show();
        $adType.parent().show();
//        $('.' + options.containerElementClass + ' .price').show();
        if ($adType.attr('price') == 'true') {
            $('.' + options.containerElementClass + ' .price').show();
        }

        // 1 -> real state
        // 2 -> housing
        if ((categoryGroupId == 1) || (categoryGroupId == 2)) {

            if (options.containerElementClass == 'searchPanel') {
                $('#address').attr('geolocate', 'true').parent().show();
            }
            else {

                if (options.containerElementClass == 'itemForm') {
                    var $map = $('#divMapForm');
                    if ($map.attr('initializeMap')) {
                        $map.initializeMap();
                    }
                    else {
                        $map.show();
                    }
                }
                else {
                    $('#divMapForm').hide();
                }
            }
        }
        else {

            if (options.containerElementClass == 'searchPanel') {
//                $('#address').attr('geolocate', 'false');
                $('#address').removeAttr('geolocate').parent().hide();
            }
        }

//        if ((options.containerElementClass == 'itemForm')
//            && ((categoryGroupId == 1) || (categoryGroupId == 2)))
//        {
//            var $map = $('#divMapForm');
//            if ($map.attr('initializeMap')) {
//                $map.initializeMap();
//            }
//            else {
//                $map.show();
//            }
//        }
//        else {
//            $('#divMapForm').hide();
//        }
    }

};

//------------------------------------------------------------------------------

jQuery.categoryMenu.accept = function() {

    var selectedCategoriesList = '';

    var categoryId = '';
    $('.categoryPanel .selectedCategory label').each(function() {
        var $this = $(this);
        categoryId = $this.attr('categoryId');
        selectedCategoriesList += $.categoryMenu.displaySelectedCategory(
            categoryId,
            $this.text()
        );
    });
    selectedCategoriesList = '<ul>' + selectedCategoriesList + '</ul>';

    var categoryGroupId = $('.categoryPanel .selectedCategory label:first')
                          .parents('.categoryGroup:first').attr('categoryGroupId');

    // if the category group id is null, it is set to blank
    if ( ! categoryGroupId) {
        categoryGroupId = '';
    }
    // if there are more than one selected categories, they are not assigned
    // to the categoryId attribute, as this attribute is only useful for 
    // only one category
    if ($('.categoryPanel .selectedCategory label').length != 1) {
        categoryId = '';
    }

    $('.searchPanel .selectedCategories')
        .attr('categoryGroupId', categoryGroupId)
        .attr('categoryId', categoryId)
        .html(selectedCategoriesList)
        // the change() event is fired to display a text if there are no
        // selected activities
        // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
        .change();
//
//    $.categoryMenu.toggleFeaturesAndAdTypes({
//        containerElementClass: 'searchPanel',
//        categoryGroupId: categoryGroupId,
//        categoryId: categoryId
//    });

    $.categoryMenu.close();
};

//------------------------------------------------------------------------------

jQuery.categoryMenu.displaySelectedCategory = function(categoryId, category) {

    var selectedCategoryHtml =
'<li checkboxId="category' + categoryId + '" categoryId="' + categoryId + '">'
+ category
+ '</li>';

    return selectedCategoryHtml;
};

//------------------------------------------------------------------------------

jQuery.categoryMenu.closeCategoryMenuTasks = function() {

    // if a scrollWindowAnimated() function is run, the action will take
    // some time, blocking the page and causing a weird behaviour if the
    // user tries to scroll the window at the same time
    $('body').scrollWindow();
};

//------------------------------------------------------------------------------

jQuery.categoryMenu.close = function() {

    $.globalFunctions.dialogClose();
    $.categoryMenu.closeCategoryMenuTasks();
};

//------------------------------------------------------------------------------
/**
 * @param button DOM element The pressed button.
 */
jQuery.categoryMenu.openNewActivityDialog = function(button) {

    $selectActivityDiv = $(button).parents('div.selectActivity');

    var dialogContent =
'<p>' + $.messages.dialog.messages.newActivityActivityGroup
+ '<strong>' + $selectActivityDiv.find('h4').text() + '</strong>.</p>'
+ '<p>' + $.messages.dialog.messages.newActivityLabel
+ ' <input type="text" id="newActivity" activityGroupId="'
+ $selectActivityDiv.attr('activityGroupId') + '" /></p>';

    var settings = {
        dialogBoxId: 'newActivityDialog',
        scrollToTop: false,
        title: $.messages.dialog.titles.newActivity,
        message: dialogContent,
        buttons: $.extend(
            {},
            $.configuration.dialog.buttons.newActivity,
            $.configuration.dialog.buttons.cancel
        ),
        width: 350
    };

    $.globalFunctions.dialogOpen(settings);

    // NOTE: The dialog box must be opened before the input field can be
    //       selected.
    $('#newActivity').select();
};

//------------------------------------------------------------------------------

//jQuery.categoryMenu.acceptNewActivity = function() {
//
//    var sanitizedValue = decodeURIComponent($('#newActivity').sanitizedValue());
//
//    if ( ! sanitizedValue) {
//        $('#newActivityDialog').errorMessage({
//             message: $.messages.validation.nameEmpty,
//             scrollToParent: false
//        });
//    }
//    else if (checkActivityBanned(sanitizedValue)) {
//
//        $('#newActivityDialog')
//            .html($.messages.dialog.messages.bannedActivity)
//            .dialog('option', 'title', $.messages.dialog.titles.bannedActivity)
//            .dialog('option', 'buttons', $.configuration.dialog.buttons.cancel);
//    }
//    else {
//
//        var activityGroup = checkActivityDuplicated(sanitizedValue);
//
//        if (activityGroup) {
//            $('#newActivityDialog')
//                .html($.messages.dialog.messages.duplicatedActivity + activityGroup + '.')
//                .dialog('option', 'title', $.messages.dialog.titles.duplicatedActivity)
//                .dialog('option', 'buttons', $.configuration.dialog.buttons.cancel);
//        }
//        else {
//            $.categoryMenu.addNewActivity(
//                sanitizedValue,
//                $('#newActivity').attr('activityGroupId')
//            );
//        }
//    }
//};

//------------------------------------------------------------------------------

//jQuery.categoryMenu.addNewActivity = function(activity, activityGroupId) {
//
//    var checkboxId = 'newActivity' + $('label.newActivity').length;
//
//    var newActivityHtml =
//'<li>'
//+ '<input type="checkbox" id="' + checkboxId + '" />'
//+ ' <label for="' + checkboxId + '" class="newActivity" activityGroupId="'
//+ activityGroupId + '">'
//+ activity
//+ '</label>'
//+ '</li>';
//
//    $('div.selectActivity[activityGroupId="' + activityGroupId + '"]')
//        .find('ul')
//        .append(newActivityHtml);
//
//    $.globalFunctions.dialogClose($('#newActivityDialog'));
//
//    // NOTE: The click event execution must go after the dialog box is
//    //       closed or it doesn't work.
//    $('#' + checkboxId)
//        .change(newActivityCheckboxChange)
//        .click()
//        .change();
//};
//
////------------------------------------------------------------------------------
///**
// * Get a list with the selected activities of the given form (item form,
// * search form, etc.).
// *
// * @param parentSelector string. The css selector of the selected activities
// *                       wrapper.
// * @return array activities
// */
//jQuery.categoryMenu.getSelectedActivities = function(parentSelector) {
//
//    var activities = [];
//
//    $(parentSelector + ' .selectedActivities li:not(.newActivity)').each(function() {
//        activities.push($.globalFunctions.sanitize($(this).text()));
//    });
//
//    return activities;
//};

//------------------------------------------------------------------------------
/**
 * Get a list with the selected activities of the given form (item form,
 * search form, etc.).
 *
 * @param parentSelector string. The css selector of the selected activities
 *                       wrapper.
 * @return array activities
 * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 */
jQuery.categoryMenu.getCategoryGroupId = function(parentSelector) {

    return $(parentSelector + ' .selectedCategories').attr('categoryGroupId');
};

//------------------------------------------------------------------------------
/**
 * Check if there are selected activities in the given form (item form,
 * search form, etc.).
 *
 * @param parentSelector string. The css selector of the selected activities
 *                       wrapper.
 * @return boolean
 */
//jQuery.categoryMenu.checkIfSelectedActivities = function(parentSelector) {
//
//    var selectedActivities = false;
//
//    if ($(parentSelector + ' .selectedActivities li').length) {
//        selectedActivities = true;
//    }
//
//    return selectedActivities;
//}

//------------------------------------------------------------------------------
/**
 * Get a list with the selected new activities of the given form (item form,
 * search form, etc.).
 *
 * @param parentSelector string. The css selector of the selected activities
 *                       wrapper.
 * @return object newActivities = {
 *      'new activity name1' => activityGroupId1,
 *      'new activity name2' => activityGroupId2,
 * }
 */
//jQuery.categoryMenu.getNewActivities = function(parentSelector) {
//
//    var newActivities = {};
//
//    $(parentSelector + ' .selectedActivities li.newActivity').each(function() {
//        var $this = $(this);
//
//        var activityName = $.globalFunctions.sanitize($this.text());
//        var activityGroupId = $.globalFunctions.sanitize($this.attr('activityGroupId'));
//
//        newActivities[activityName] = activityGroupId;
//    });
//
//    return newActivities;
//};

//------------------------------------------------------------------------------
/**
 * Get a list with the selected new activity ids of the given form (item form,
 * search form, etc.).
 *
 * @param parentSelector string. The css selector of the selected activities
 *                      wrapper.
 * @return array activityIds
 */
jQuery.categoryMenu.getSelectedCategoryIds = function(parentSelector) {

    var categoryIds = [];

    $(parentSelector + ' .selectedCategories li').each(function() {
        categoryIds.push($.globalFunctions.sanitize($(this).attr('categoryId')));
    });

    return categoryIds;
};

//------------------------------------------------------------------------------
// private functions -----------------------------------------------------------
//------------------------------------------------------------------------------
/**
 * @param activity string
 * @return boolean
 */
//function checkActivityBanned(activity) {
//
//    var activityBanned = false;
//
//    activity = activity.toLowerCase();
//
//    // this function is not supposed to be required often, so it is not
//    // worth to break the loop when the duplicated condition becomes true
//    $('.selectActivity.' + $.configuration.bannedClass + ' span').each(function() {
//
//        if ($(this).text().toLowerCase() == activity) {
//            activityBanned = true;
//        }
//    });
//
//    return activityBanned;
//};

//------------------------------------------------------------------------------
/**
 * @param activity string
 * @return string activityGroup The activity group where the activity
 *         is, or blank string if the activity is not duplicated.
 */
function checkActivityDuplicated(activity) {

    var activityGroup = '';

    activity = activity.toLowerCase();

    // this function is not supposed to be required often, so it is not
    // worth to break the loop when the duplicated condition becomes true
    $('.selectActivity label').each(function() {

        if ($(this).text().toLowerCase() == activity) {
            activityGroup = $(this).parents('div.selectActivity').find('h4').text();
        }
    });

    return activityGroup;
};

//------------------------------------------------------------------------------
/**
 * Check if there are selected categories in groups different to the group
 * of the given element.
 *
 * @param $element jQuery element
 * @return boolean
 */
function checkMultigroup($element) {

    var multigroup = false;

    if ($('.categoryPanel .selectedCategory').length) {
        // the category group id of the first element is checked, because
        // all the selected categories must belong to the same group
        var selectedGroupId = $('.categoryPanel .selectedCategory:first')
            .parents('.categoryGroup:first').attr('categoryGroupId');

        if (selectedGroupId !=
            $element.parents('.categoryGroup:first').attr('categoryGroupId'))
        {
            multigroup = true;
        }
    }
    return multigroup;
};

//------------------------------------------------------------------------------

})(jQuery);

/**                                                                          **/
/**                              Category menu                               **/
/**                                                                          **/
/******************************************************************************/


