define(['jquery', 'url-parse', 'cla_select2'], function (jQuery, Url) {

    var People = {};

    People.init = function () {
        var people_container = jQuery('.people-ajax-container');

        people_container.on('click', '.js-view-switcher', People.switchView);
        people_container.on('click', '.toggle-a-z-field', People.switchAZField);

        // Asynchronise - ajax links, pagination links and table header links (sorting)
        people_container.on('click', '.js-people-ajax-link, .pagination a, thead th:not(.js-people-not-ajax-link) a', function(e) {
            People.ajaxClickHandler(this, e);
        });

        people_container.on('submit', '#form_filter', function(e) {
            People.ajaxSearchHandler(this, e);
        });

        people_container.on('keypress', '#search_terms', People.formSearch);

        people_container.on('keydown', '.advanced-search-wrapper', People.advancedFormKeypress);

        people_container.on('focus', '#search_terms', { state : false }, People.toggleSearch);

        people_container.on('click', '.js-toggle-advanced-search', {}, People.toggleSearch);

        people_container.on('click', '#people_submit', function(e) {
            People.ajaxSearchHandler(this, e);
        });

        people_container.on('click', '.js-advanced-search-submit', function(e) {
            People.AdvancedSearch(this, e);
        });

        people_container.on('show-search', '#advancedSearch', People.setHeight);

        People.InitExtranetAreaSelect();
        People.InitMetadataAjaxSelects();

        jQuery('select.select2:not(.js-no-auto-select2)').select2();

        jQuery(document).ajaxStart(function() {
            jQuery('#spinner').show();
        })
            .ajaxStop(function() {
                jQuery('#spinner').hide();
            });
    };

    People.ajaxCall = function(query, params){
        // Remove tooltips now or the AJAX update will leave them on the screen until a page reload.
        jQuery('.js-view-switcher').tooltip('hide');

        var params = params || {};

        var adv_filter = jQuery('#adv_filter').val();
        if (adv_filter !== '')
            params.adv_filter = adv_filter;

        params.ajax = 1;

        $('.js-advanced-search-submit').attr('disabled', 'disabled');

        jQuery.ajax({
            url: query,
            type: 'GET',
            data: params,
            success: function(result, status, xhr){
                jQuery('.people-ajax-container').html(result);
                People.InitExtranetAreaSelect();
                People.InitMetadataAjaxSelects();
                jQuery('select.select2:not(.js-no-auto-select2)').select2();
            }
        });
    };

    People.ajaxClickHandler = function (target, e) {
        var query = jQuery(target).attr('href');

        e.preventDefault();

        People.ajaxCall(query);
        People.updateHistory(query);
    };

    People.ajaxSearchHandler = function (target, e) {
        e.preventDefault();
        var form = jQuery(target).closest("form");
        var action = form.attr('action');
        var use_db = parseInt($('input[name="use_db"]').val());
        var search_terms = $('#search_terms').val();
        var parsed_action = new Url(action, null, true);


        jQuery(".include-search-parameter").find(':input').map(function(){
            parsed_action.query[this.name] = this.value;
        });

        if (use_db)
            parsed_action.query['use_db'] = 1;

        if (search_terms !== '')
            parsed_action.query['search_terms'] = search_terms;

        var url = parsed_action.toString();

        People.ajaxCall(url);
        People.updateHistory(url);

    };

// set height of advanced search window so it doesn't exceed the page height
    People.setHeight = function(){
        var pageH = jQuery(window).height(),
            advSearchTop = jQuery(this).offset().top,
            maxHeight = (pageH - advSearchTop) - 157,
            desktopSize = jQuery(window).width() >= 767;

        if( desktopSize) {
            jQuery('.advanced-search-wrapper').css({ 'max-height' : maxHeight})
        } else {
            jQuery('.advanced-search-wrapper').css({ 'max-height' : '100%'})
        }
    };

    People.updateHistory = function(query, params){
        var params = params || {};
        var use_db_link = $('#use-db-link');

        var adv_filter = jQuery('#adv_filter').val();
        if (adv_filter !== '')
            params.adv_filter = adv_filter;

        if (window.history.pushState) {
            var url = query;
            var parsed_url = new Url(url, null, true);

            for (param in params)
                parsed_url.query[param] = params[param];

            url = parsed_url.toString();
            window.history.pushState({}, '', url);

            parsed_url.query['use_db'] = 1;
            use_db_link.attr('href', parsed_url.toString());
        }
    };

    People.switchView = function(evt)
    {
        var view_type = jQuery(this).data('viewtype'),
            query = document.location.href,
            params;

        evt.preventDefault();

        if (query.indexOf('view_style=') !== -1)
        {
            // Replace current URL param
            var old_style = jQuery('#view_style').val();
            query = query.replace('view_style=' + old_style, 'view_style=' + view_type);
        } else
        {
            // Add URL param
            var seperator = (query.indexOf('?') === -1) ? '?' : '&';

            var parts = query.split('#');
            var anchor = '';
            if (parts.length > 1)
                anchor = '#' + parts[1];

            query = parts[0] + seperator + 'view_style=' + view_type + anchor;
        }

        params = {
            'form_filter': true
        };
        People.updateHistory(query);
        People.ajaxCall(query, params);
    };

    People.toggleSearch = function (e) {
        var className = 'people-search-show',
            target = '#peopleSearch';

        e.preventDefault();
        jQuery(target).toggleClass(className, e.data.state);

        // bind escape key to close advanced search
        if(jQuery(target).hasClass(className)) {
            // bind event
            jQuery('body').on('keydown', function(e){
                // check for escape
                if(e.which === 27) {
                    jQuery(target).removeClass(className);
                }
            });
            jQuery('#advancedSearch').trigger('show-search');
        } else {
            // unbind escape keying
            jQuery('body').off('keydown');
        }
        return false;
    };

    People.formSearch = function (e){
        // Make enter submit the search, not submit the entire form
        if (e.which == 13) {
            jQuery('#people_submit').click();
            e.preventDefault();
        }
    };

    People.advancedFormKeypress = function (e){
        if (e.which == 13)
        {
            // Make enter submit the search, not submit the entire form
            jQuery('.js-advanced-search-submit').click();
            e.preventDefault();
        }
        if (e.keyCode == 27)
        {
            // Escape closes the advanced search
            e.data = {state: false};
            People.toggleSearch(e);
            e.preventDefault();
        }

    };

    People.switchAZField = function (e) {
        var cur_field = jQuery('#a_z_field').val(),
            url = window.location.href,
            new_field = cur_field === 'surname' ? 'firstname' : 'surname',
            params = {
                'form_filter': true,
                'a_z_field': new_field
            };

        e.preventDefault();

        People.ajaxCall(url, params);
    };

    People.InitExtranetAreaSelect = function() {
        var el = jQuery('#select2_ex_area_ids');
        if (el.length) {
            el.select2({
                ajax: {
                    url: "/intranet/common/gre_picker_server.php?type=extranet",
                    dataType: 'json',
                    data: function (params) {
                        return {
                            kw: params.term, // search term
                            page: params.page - 1
                        };
                    },
                    processResults: function (data) {
                        return {results: data.data, more: data.more};
                    }
                }
            });
        }
    };

    People.InitMetadataAjaxSelects = function() {
        jQuery('.js-select2-ajax').each(function()
        {
            var dropdown = $(this);
            var id = dropdown.attr('id');
            dropdown.select2({
                ajax: {
                    url: "/intranet/people/metadata_select_server.php?field=" + id,
                    dataType: 'json',
                    data: function (params) {
                        return {
                            kw: params.term,
                            page: params.page -1
                        };
                    },
                    processResults: function (data) {
                        return {results: data.data, more: data.more};
                    }
                }
            });
        });
    };

    People.AdvancedSearch = function(target, e) {
        e.preventDefault();
        People.GetAdvancedSearchFields();
    };

    People.GetAdvancedSearchFields = function()
    {
        var form_values = {
            keywords:				jQuery('#as_keywords').val(),
            keywords_condition:		jQuery('#as_keywords_condition').val(),
            firstname:				jQuery('#as_firstname').val(),
            surname:				jQuery('#as_surname').val(),
            job_title:				jQuery('#as_job_title').val(),
            company: 				jQuery('#as_company').val(),
            roles: 					People.GetSelectedFieldNames('roles'),
            groups: 				People.GetSelectedFieldNames('groups'),
            include_subgroups:		jQuery('#as_include_subgroups').is(':checked'),
            ex_area_ids:			People.GetSelectedFieldNames('ex_area_ids'),
            intranetuser:			jQuery('#as_intranetuser').val(),
            username:				jQuery('#as_username').val(),
            emailad:				jQuery('#as_emailad').val()
        };
        var search_strings = [];
        var paging_params = jQuery('#paging_params').val();
        var rows_per_page = jQuery('#as_rows_per_page').val();
        var visible_columns = jQuery.parseJSON((jQuery('#search_columns').val()));

        if (form_values.intranetuser == 'default')
            form_values.intranetuser = null;

        // Get any metadata fields
        var result;
        for (var md_key in visible_columns)
        {
            if (visible_columns[md_key].indexOf('[m]') == 0)
            {
                var field_name = visible_columns[md_key].substring(3);

                result = People.GetFilterFromForm(field_name);

                if (result !== null)
                    search_strings.push(encodeURIComponent(result));
            }
        }

        for (var key in form_values)
        {
            var v = form_values[key];
            if (((typeof v === 'object') &&
                (v !== null)) ||
                ((typeof v === 'string') &&
                    (v !== '')))
            {
                result = null;

                if (key == 'keywords_condition')
                {
                    if (v == 'all')
                        result = 'keyword_match:ALL';
                } else
                {
                    result = People.GetFilterFromForm(key);
                }
                if (result !== null)
                    search_strings.push(encodeURIComponent(result));
            }
        }

        if ((form_values['groups'] !== null) &&
            (form_values['include_subgroups'] === true))
        {
            search_strings.push(encodeURIComponent('+groups'));
        }

        var params = [];
        if (paging_params.length > 0)
            params.push(paging_params);
        params.push('search_terms=' + search_strings.join(' '));
        if (rows_per_page.length > 0)
            params.push('rows_per_page=' + rows_per_page);

        var form = jQuery('#people_submit').closest("form");
        var action = form.attr('action');

        var action_parts = action.split('#');
        var url_anchor = '';
        if (action_parts.length > 1)
            url_anchor = '#' + action_parts[1];

        var seperator = action.indexOf('?') > -1 ? '&' : '?';
        var url = action_parts[0] + seperator + params.join('&') + url_anchor;

        People.ajaxCall(url);
        People.updateHistory(url);
    };

    People.GetFilterFromForm = function(field_name)
    {
        var result = null;

        var field = jQuery('#' + field_name);
        var field_as = jQuery('#as_' + field_name);

        var value = People.GetSelectedFieldNames(field_name);
        if (value === null)
            value = field_as.val();

        if (typeof value === 'undefined')
            value = field.val();

        if (field.data("type") == 13) // 13 == HTML_COMPONENT_DATE
        {
            var from = jQuery("#" + field_name + "_from");
            var to = jQuery("#" + field_name + "_to");

            if (from.val() || to.val()) {
                value = [];
                value.push(from.val(), to.val());
            }
        }

        var title = field.data('title');
        if (typeof title == 'undefined')
            title = jQuery('#select2_' + field_name).data('title');
        if (typeof title == 'undefined')
            title = field_as.data('title');

        // Checkbox from metadata, we should add no filter if set to 'Any'
        if (field.data('type') == 5)    // 5 == HTML_COMPONENT_CHECK
        {
            if (field.val() == 'any')
                value = null;
        }

        // 'Any' or 'All' select at the side of the field
        var any = true;

        if ((typeof value !== 'undefined' && value !== null))
        {
            // If a single value, add it the the array
            var value_array = [];
            if ((typeof value === 'Array') ||
                (typeof value === 'object'))
                value_array = value;
            else
                value_array.push(value);

            // Only process at all if there was a filter set
            if ((value_array.length > 1) ||
                (value_array.length === 1 && value_array[0] !== ''))
            {
                var enclose = (value_array.length !== 1);

                if ((enclose) &&
                    (jQuery('#any_all_' + field_name).val() === 'ALL'))
                    any = false;

                var entry = title + ':';

                // Show bare keywords instead of in a named pair
                if (field_name === 'keywords')
                    entry = '';

                if (enclose)
                    entry = entry + '(';
                for (var i = 0; i < value_array.length; i++)
                {
                    var item = value_array[i];
                    if ((item.indexOf(' ') !== -1) &&
                        (field_name !== 'keywords'))
                        item = '"' + item + '"';
                    if (!any)
                        item = '+' + item;

                    value_array[i] = item;
                }
                entry = entry + value_array.join(',');
                if (enclose)
                    entry = entry + ')';

                result = entry;
            }
        }

        return result;
    };

    /**
     * Return an array of selected field names, not the values associated with them
     */
    People.GetSelectedFieldNames = function(type)
    {
        var roles = [];
        jQuery('#' + type + ' option:selected').each(function()
        {
            roles.push($(this).text());
        });
        jQuery('#select2_' + type + ' option:selected').each(function()
        {
            roles.push($(this).text());
        });

        if (roles.length == 0)
            roles = null;

        return roles;
    };

    return People;
});
