/**
 * Init Interface
 */
$(function() {
    // init object-linked things
    initInterfaceObject($(document));

    // init live things
    initInterfaceLive();

    // init general interface items
    initInterfaceLayout();
});

/**
 * Init interface elements
 */
function initInterfaceLayout()
{
    // adv search - check if form in use
    var advSearchUsed = $.isFilled('#I-advsearch > form');
    if (advSearchUsed) {
        $('#I-advsearch-button').addClass('inuse');
    }

    // if we need to open form by default
    var hasSearch = (location.search.indexOf('query%5B') !== -1) || (location.search.indexOf('search%5B') !== -1);
    if ((!advSearchUsed || !hasSearch) && $('#I-advsearch[rel=open-first]').length) {
        $('#I-title > #I-advsearch-button').click();

        // if there is message present - move to left
        $('#container div.msg').addClass('left');
    }

    // handle hover in drop down menu (for touch devices)
    $('#I-bar-menu > li').click(function() {return true;});

    // if we need to run clock
    if ($('#I-run-time').length) {
        setInterval(initRunTime, 1000);
    }

    // move to results
    var _results = $('a[name=results]');
    if (_results.length) {
        $('html,body').animate({scrollTop: _results.offset().top}, 'fast');
    }
}

/**
 * Init Ovject things
 * Anything that is inited for each object separately
 */
function initInterfaceObject(obj)
{
    // cross-block of edit code and code name at the same time
    obj.find('input[rel^=block-group-]').each(function () {
        var other = $('input[rel='+$(this).attr('rel')+']').not($(this));
        // TODO: remove parents search on rework to ajax suggestions
        if ($(this).val()) {
            $(this).removeAttr('disabled');
            other.attr('disabled', 'disabled').parents('div.x-code-block').find('div').css('visibility', 'hidden');
        } else {
            other.removeAttr('disabled').parents('div.x-code-block').find('div').css('visibility', 'visible');
        }
    });

    // .list - fixed header
    obj.find('table.list:not(.no-fixed)').fixedtableheader();

    // remove existing multiple to avoid duplicates
    obj.find('button.ui-multiselect').unbind().remove();

    // init multiple selectboxes
    obj.find('select[multiple]:not(.select-header)').multiselect({
        header: false,
        minWidth: 'auto',
        noneSelectedText: '...',
        selectedList: 999
    });

    // init multiple selectboxes
    obj.find('select[multiple].select-header').multiselect({
        header: true,
        checkAllText: L['select-check-all'],
        uncheckAllText: L['select-uncheck-all'],
        minWidth: 'auto',
        noneSelectedText: '...',
        selectedList: 999
    });

    // init smart selectboxes
    obj.find('select.smart').multiselect({
        multiple: false,
        header: false,
        height: 149,
        minWidth: 'auto',
        noneSelectedText: '...',
        selectedList: 999
    });

    // init calendars
    obj.find('input.date').removeClass('hasDatepicker').datepicker({
        firstDay: 1,
        gotoCurrent: true,
        changeMonth: true,
        changeYear: true,
        showOtherMonths: true,
        yearRange: '-10:+3',
        selectOtherMonths: true,
        dateFormat: 'yy-mm-dd',
        constrainInput: false
    });

    obj.find('input.time').removeClass('hasDatepicker').timepicker({
        showButtonPanel: false,
        showMinute: true,
        showSecond: true,
        timeFormat: 'HH:mm:ss',
        timeOnlyTitle: ''
    });

    obj.find('input.time-hours').removeClass('hasDatepicker').timepicker({
        showButtonPanel: false,
        showMinute: false,
        showSecond: false,
        timeFormat: 'HH:mm:ss',
        timeOnlyTitle: ''
    });


    obj.find('input.datetime').removeClass('hasDatepicker').datetimepicker({
        dateFormat: 'yy-mm-dd',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        showOtherMonths: true,
        selectOtherMonths: true,
        yearRange: '-10:+3',
        showSecond: true,
        showButtonPanel: false,
        timeFormat: 'HH:mm:ss'
    });
    obj.find('input.datetimetz').removeClass('hasDatepicker').datetimepicker({
        dateFormat: 'yy-mm-dd',
        firstDay: 1,
        changeMonth: true,
        changeYear: true,
        showOtherMonths: true,
        selectOtherMonths: true,
        yearRange: '-10:+3',
        showSecond: true,
        showTimezone: true,
        timezoneText: '',
        showButtonPanel: false,
        timeFormat: 'HH:mm:ssz'
    });

    // init hover tooltips
    obj.find('*[rel=tooltip]').tooltip({
        track: true,
        delay: 100,
        showURL: false,
        bodyHandler: function() {
            return $('<div/>').append($('#'+this.id+'-tooltip').clone().removeClass('tooltip')).html();
        },
        fade: false,
        top:10
    });
    obj.find('span[rel=helptip]').tooltip({
        track: true,
        delay: 0,
        showURL: false,
        bodyHandler: function() {
            return $('<div/>').append($('#'+this.id+'-tooltip').clone().removeClass('tooltip')).html();
        },
        extraClass:'helptip',
        fade:false
    });

    // init sortable
    obj.find('.sortable').sortable({
        handle:'.handle',
        helper: function(e, tr) {
            var $originals = tr.children();
            var $helper = tr.clone();
            $helper.children().each(function(index)
            {
              $(this).width($originals.eq(index).width())
            });
            return $helper;
        }
    });
    obj.find('.sortable .handle').disableSelection();

    // check forms with advanced blocks in use
    obj.find('form .advanced').each(function () {
        if ($.isFilled($(this).find(':input'))) {
            $(this).show();
        }
    });

    // handle edit of any field related to period select
    obj.find('select.x-period').on('change', function () {
        var eField = $(this);
        var type = eField.val();
        if (type == 'custom') {
            return true;
        }

        // calculate period
        period = calcPeriod(type);

        // fill it
        if (eField.attr('x:start_date')) {
            $('#' + eField.attr('x:start_date')).val(period['startDate']);
        }
        if (eField.attr('x:start_time')) {
            $('#' + eField.attr('x:start_time')).val(period['startTime']);
        }
        if (eField.attr('x:stop_date')) {
            $('#' + eField.attr('x:stop_date')).val(period['stopDate']);
        }
        if (eField.attr('x:stop_time')) {
            $('#' + eField.attr('x:stop_time')).val(period['stopTime']);
        }
    }).each(function () {
        var eSelector = $(this);
        var fields = ['start_date', 'start_time', 'stop_date', 'stop_time'];

        // handle on edit of this fields
        for(f in fields) {
            var field = eSelector.attr('x:'+fields[f]);
            if (!field) {
                continue;
            }
            $('#' + field).data('x:period', $(this)).on('keyup change', function () {
                $(this).data('x:period').val('custom');
            });
        }

        // if default specified and start date is empty - set it
        if (eSelector.attr('x:default') && eSelector.attr('x:start_date')) {
            if ($('#' + eSelector.attr('x:start_date')).val() == '') {
                eSelector.val(eSelector.attr('x:default')).change();
            }
        }
    });

    // init autoreload blocks
    obj.find('.x-autoreload, .d-autoreload').each(function () {
        var autoreload_type_flag = 'arInterval';
        if ($(this).hasClass('d-autoreload')) {
            // dashboard cookies
            autoreload_type_flag = 'darInterval';
            $('#darinterval').val(getCookie(autoreload_type_flag));
        }
        var reloadData = function (autoreload_type_flag, eBlock) {
            if (autoreload_type_flag == 'arInterval') {
                // disable ajax cache
                $.ajaxSetup({cache: false});
                $.get(location.href, function (data) {
                    dynSearchLoad(data, 'DYNROWS', eBlock);
                    $(eBlock).trigger('reloadData');
                }, 'html');
            } else if (autoreload_type_flag == 'darInterval') {
                for (var widget_name in post_params) {
                    $("#" + widget_name + "_loader").show();
                    dashboard_widgets[widget_name].setParamsToForm();
                    var parameters = {};
                    parameters = {SID: getCookie('PHPSESSID'), name: dashboard_widgets[widget_name].type, full_name: dashboard_widgets[widget_name].name};
                    $.each($('#'+widget_name+'-form').serializeArray(), function(i, field) {
                       parameters[field.name] = field.value;
                    });
                    parameters = JSON.stringify ({jsonrpc:'2.0',method:'dashboard.info', params:parameters || [], id: 'jsonrpc'} )
                    dashboard_widgets[widget_name].updateWidget(parameters);
                    $("#"+dashboard_widgets[widget_name].name+"_loader").hide();
                }
            }
        };
        // Specific dashboard actions
        if ($(this).hasClass('d-autoreload')) {
            // set counts from cookies or 1
            obj.find('select[id^=count_charts_]').each(function () {
                var count_charts = getCookie($(this).attr('id'));
                $(this).val( count_charts != '' ? count_charts : 1 );
            });
            $(document).ready(function() {
                reloadData(autoreload_type_flag, [this]);
                for (var widget_name in post_params) {
                    dashboard_widgets[widget_name].setParamsToForm();
                    dashboard_widgets[widget_name].checkCodeAndCodename();
                    $('#'+widget_name+'-form div input').bind('change', function() {
                        dashboard_widgets[widget_name].setToCookie(this);
                        dashboard_widgets[widget_name].setParamsToForm();
                        reloadData(autoreload_type_flag, [this]);
                    });
                }
            });
        }
        // get interval
        var ari = $('#' + $(this).attr('x:interval'));
        ari = ari.length ? parseInt(ari.val()) : 10;
        // init autoreload
        $(this).data(autoreload_type_flag, setInterval(reloadData, ari * 1000, autoreload_type_flag, [this]));
        // handle change of interval
        $(document).on('change', '#' + $(this).attr('x:interval'), function () {
            setCookie(autoreload_type_flag, $(this).val(), 14, location.pathname);
            location.reload();
        });
    });

    return obj;
}

/**
 * Init Live things
 * Anything that is inited once for the document, even new added elements
 */
function initInterfaceLive()
{
    // .list - click on row
    $(document).on('click', 'table.list:not(.no-active) > tbody > tr', function (e) {
        if (!$(e.target).is('input,select,textarea')) {
            $(this).toggleClass('active');
        }
    });

    // .list - checkbox in header
    $(document).on('change', 'table.list > thead input[type=checkbox]', function () {
        if (!$(this).attr('rel')) {
            return;
        }

        // get list of inputs and either set or remove change attribute
        var inputs = $(this).parents('table.list').find('tbody input[type=checkbox][rel='+$(this).attr('rel')+']:not([disabled])');
        if ($(this).attr('checked')) {
            inputs.attr('checked', 'checked');
        } else {
            inputs.removeAttr('checked');
        }

        // fire change event
        inputs.change();
    });

    // .list - checkbox in subheader
    $(document).on('change', 'table.list > tbody > tr.subheader input[type=checkbox]', function () {
        if (!$(this).attr('rel')) {
            return;
        }

        // get list of inputs and either set or remove change attribute
        var inputs = $(this).parents('tbody').find('tr input[type=checkbox][rel='+$(this).attr('rel')+']:not([disabled])').not($(this));
        if ($(this).attr('checked')) {
            inputs.attr('checked', 'checked');
        } else {
            inputs.removeAttr('checked');
        }

        // fire change event
        inputs.change();
    });

    // .list - paging form
    $(document).on('change', '.p-extra select', function () {
        listPagesSubmit($(this).closest('.p-extra'));
        return false;
    });
    $(document).on('keypress', '.p-extra input', function (e) {
        var code = e.keyCode || e.which;
        if (code == 13) {
            listPagesSubmit($(this).closest('.p-extra'));
            return false;
        }
        return true;
    });

    // init onclick tooltips
    $(document)
        .on('showMe', '.tooltip-box', function () {
            // add class to the link
            $('#'+$(this).attr('id').replace('-tooltip', '')+'.tooltip-link').addClass('tooltip-visible');
            // show box
            $(this).fadeIn('fast');
            // check multiselect elements with
            $(this).find('select[multiple],select.smart').multiselect('refreshWidth');
        })
        .on('hideMe', '.tooltip-box', function () {
            // add class to the link
            $('#'+$(this).attr('id').replace('-tooltip', '')+'.tooltip-link').removeClass('tooltip-visible');
            // show box
            $(this).fadeOut('fast');
        })
        .on('click', '.tooltip-box', function (e) {
            // do not close tooltip box if it was clicked
            if ($(this).has(e.target).length !== 0) {
                e.stopPropagation();
            }
        });
    $(document).on('click', '.tooltip-link', function (e) {
        // get id for related tooltip box
        var obj = $('#' + $(this).attr('id')+'-tooltip');

        if (obj.is(':visible')) {
            obj.trigger('hideMe');
        } else {
            $(document).trigger('click');
            obj.trigger('showMe');
        }

        return false;
    });
    $(document).on('click', function (e) {
        // do not close tooltips if click on datepicker widget (it attached to body)
        if ($('#ui-datepicker-div').has(e.target).length || $(e.target).closest('.ui-datepicker-prev,.ui-datepicker-next').length) {
            return;
        }
        // do not close tooltips if click on multiselect opened block
        if ($('.ui-multiselect-menu').has(e.target).length !== 0) {
            return;
        }

        // check if we need to close tooltips on body click
        $('.tooltip-box:visible').each(function (e) {
            if ($(this).has(e.target).length === 0) {
                $(this).trigger('hideMe');
            }
        });

        // check if we need to close advsearch
        if ($('#I-advsearch:not(.opened) > form:visible').length) {
            if ($(e.target).is('#I-advsearch-button')) {
                return;
            }
            if ($('#I-advsearch').has(e.target).length === 0) {
                $('#I-advsearch-button').click()
            }
        }
    });

    // init popup links
    $(document).on('click', 'a[rel*=popup]', function (e) {
        // stop propagation of the event first
        e.stopPropagation();
        this.blur();

        if ($(this).attr('rel').indexOf('delete') != -1) {
            if (!confirm(L['deleteConfirm'])) {
                return false;
            }
        }
        var info = $(this).attr('rel').match(/popup-(\d+)x(\d+)/);
        if (info != null) {
            winOpen(this.href, parseInt(info[1]), parseInt(info[2]));
        } else {
            winOpen(this.href);
        }
        return false;
    });

    // smart search - run ajax search in smart search (not for popups)
    if ($('body.L-main').length) {
        $(document).on('keyup', '#I-title #search-_q', dynSearchRun);
    }

    // adv search - button
    $(document).on('click', '#I-title > #I-advsearch-button', function () {
        $('#I-advsearch-button').toggleClass('open');
        $('#I-advsearch').find('> form').slideToggle();

        // check multiselect elements with
        if ($('#I-advsearch').is(':visible')) {
            $('#I-advsearch').find('select[multiple],select.smart').multiselect('refreshWidth');
        }
    });

    // adv search - include smart search in advsearch
    $(document).on('submit', '#I-advsearch > form', function () {
        if (!$(this).find('input[name="search[_q]"]').length) {
            $(this).append($('<input type="hidden" name="search[_q]" />').val($('#search-_q').val()));
        }
    });

    // adv search - handle reset button
    $(document).on('click', '#I-advsearch > form input[rel=reset]', function () {
        var q = $(this).parents('form').find('input[type=hidden]').serialize();
        location.href = location.pathname + (q ? '?' + q : '');
    });

    // adv search - handle search processing
    $(document).on('submit', '#I-advsearch > form', function () {
        // check query output type
        var ot = $(this).find('#query-output');
        if (!ot.val() || ot.val() == 'web') {
            loading();
        }
        return true;
    });

    // handle advanced blocks in forms (mostly advanced search)
    $(document).on('click', 'form input[rel=advanced]', function () {
        var eBlock = $(this).parents('form').find('.advanced');
        eBlock.slideToggle(200);
        if (eBlock.is(':visible')) {
            // check multiselect elements with
            eBlock.find('select[multiple],select.smart').multiselect('refreshWidth');
        }
    })

    // init resize of multiple selectboxes
    $(window).on('resize', function () {
        $('select[multiple],select.smart').multiselect('refreshWidth');
    })

    // cross-block of edit code and code name at the same time
    $(document).on('keyup', 'input[rel^=block-group-]', function () {
        var other = $('input[rel='+$(this).attr('rel')+']').not($(this));
        // TODO: remove parents search on rework to ajax suggestions
        if ($(this).val()) {
            $(this).removeAttr('disabled');
            other.attr('disabled', 'disabled').parents('div.x-code-block').find('div').css('visibility', 'hidden');
        } else {
            other.removeAttr('disabled').parents('div.x-code-block').find('div').css('visibility', 'visible');
        }
    });

    // toggle blocks right after header with checkbox
    $('header input[type=checkbox]').on('change', function () {
        if ($(this).is(':checked')) {
            $(this).parents('header').nextAll('table.form').first().removeClass('disabled');
        } else {
            $(this).parents('header').nextAll('table.form').first().addClass('disabled');
        }
    }).change();
}

/**
 * Makes submit without form tag in the caption of .list
 */
function listPagesSubmit(form)
{
    var q = form.find('input,select').serialize();
    form.trigger('hideMe');
    location.href = location.pathname + '?' + q;
}

/**
 * Runs time in text
 */
function initRunTime()
{
    el = $('#I-run-time');

    var tzU = el.attr('mb:tzU');
    var tzL = el.attr('mb:tzL');

    serverTz = (tzL%100 + Math.floor(tzL/100)*60)*60;

    stamp = el.attr('mb:stamp');
    stamp = stamp*1 + 1;
    el.attr('mb:stamp', stamp);

    d = new Date();
    d = new Date(stamp * 1000 + d.getTimezoneOffset()*60*1000 + serverTz*1000);

    els = new Array();
    els['%Y'] = d.getFullYear();
    els['%y'] = d.getYear();
    els['%m'] = printf("%02d", d.getMonth()+1);
    els['%n'] = d.getMonth();
    els['%d'] = printf("%02d", d.getDate());
    els['%j'] = d.getDate();
    els['%h'] = d.getUTCHours();
    els['%H'] = printf("%02d", d.getHours());
    els['%M'] = printf("%02d", d.getMinutes());
    els['%S'] = printf("%02d", d.getSeconds());
    els['%N'] = d.getDay();
    els['%Z'] = tzU;
    els['%z'] = tzL;

    format = el.attr('mb:format');
    if (format == undefined) {
        format = 'Y-m-d H:i:s';
    }

    for(key in els) {
        format = format.replace(key, els[key])
    }

    el.html(format);
}

/**
 * Populate dynamic area of the documents
 *
 * @param data        new data for the documents
 * @param search_tag  name of tag that mark dynamic area
 * @param container   name of container in the document to populate
 */
function dynSearchLoad(data, search_tag, container)
{
    // get only dynamic part
    data = data.substring(data.indexOf('<!-- ' + search_tag + ' -->'), data.lastIndexOf('<!-- ' + search_tag + ' -->'));

    // find container
    var c = $(container ? container : '#container');

    // update its contents
    c.html(data);

    // re-init dynamic elements
    initInterfaceObject(c);
}

/**
 * Handler for smart search input field - preserve last search and
 * load new data only if query changed and it is more then 3 chars
 */
var dynSearchQ = '';
function dynSearchRun()
{
    // check the query
    var q = $(this).val().trim();
    if (q == dynSearchQ || (q.length > 0 && q.length < 3)) {
        return;
    }
    dynSearchQ = q;

    // build an url
    dynSearchUrl = location.pathname + '?' + $(this).closest('form').serialize();

    // run new timer
    setTimeout(function () {
        // if nothing new typed - then make a request
        if (q == dynSearchQ) {
            $.get(dynSearchUrl, {}, function (data) {dynSearchLoad(data, 'DYNAREA');}, 'html');
        }
    }, 300);
}
