(function(){
    window.admin = {};
    var it = window.admin;
    var servlet = {
        'direct' : {
            'dyna_select' : 'http://'+punycode.ToASCII(window.location.host)+':8888/dyna_select/dyna_select',
            'files_upload4' : 'http://'+punycode.ToASCII(window.location.host)+':8888/multifiles2/miltifiles2class',
            'upload2base2' : 'http://'+punycode.ToASCII(window.location.host)+':8888/file2os2base/file2os2baseclass'
        },
        'dyna_select' : 'http://'+punycode.ToASCII(window.location.host)+'/dyna_select/dyna_select',
        'files_upload4' : 'http://'+punycode.ToASCII(window.location.host)+'/multifiles2/miltifiles2class',
        'upload2base2' : 'http://'+punycode.ToASCII(window.location.host)+'/file2os2base/file2os2baseclass'
    };
    var share = {
        'cun' : undefined,
        'form' : undefined,
        'frame' : undefined,
        'icon' : undefined,
        'callback' : undefined,
        'upls' : undefined,
        'uploaded' : undefined
    };
    
    it.toServlet = function(source, servlet, data) {
        jQuery.ajax({
            url: servlet,
            type: 'POST',
            dataType: 'json',
            data: data,
            success: function (resp) {
                if (resp.errors.length > 0) {
                    var str = '';
                    for (var i = 0; i < resp.errors.length; i++)
                        str += resp.errors[i] + "\n";
                    if (resp.action !== 'delete')
                        if (source !== null && source !== undefined) upd.run(source);
                    alert(str);
                } else {
                    if (source !== null && source !== undefined) upd.run(source);
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (source !== null && source !== undefined) upd.run(source);
            }
        });
        return false;
    }
        
    it.form = function(icon, title, callback) {
        share = {};
        share.upls = [];
        share.icon = icon;
        share.uploaded = 0;
        share.frame = new CFrame(title, 'm-adm-width');
        share.frame.setContent(icon.childNodes[0].nodeValue);
        share.form = byId('admForm');
        jQuery('#b-frameRoundWhite-close').click(function(){
            removeUploadButtons();
        });
        if (callback !== undefined) share.callback = callback;
        jQuery('#admForm .adm-multifile, #admForm .adm-file, #admForm .adm-image').each(function() {
            switch (this.getAttribute('data-type')) {
                case 'multifile':
                    bindMultifile(jQuery(this).find('.b-files-upload')[0]);
                    break;
                case 'file':
                    bindFile(jQuery(this).find('.b-files-upload')[0]);
                    break;
            }
        });
        jQuery('#admForm .jquery-munrusSelector').munrusSelector({
            source: function (response, args) {
                return jQuery.ajax({
                    'url' : servlet.dyna_select,
                    'type' : 'POST',
                    'dataType' : 'json',
                    'data' : args,
                    'success' : function (data) {
                        response(jQuery.map(data.items,
                            function (item) {
                                return {
                                    'label': item.value,
                                    'value': item.id
                                }
                            }));
                    }
                });
            }
        });
    //console.log(share.upls.length);
    }
    
    it.multifileDelete = function(el, fid) {
        el.parentNode.parentNode.removeChild(el.parentNode);
        jQuery.ajax({
            url: servlet.files_upload4,
            type: 'POST',
            dataType: 'json',
            data: {
                'fid' : fid,
                'smode' : 'delete'
            }
        });
        refreshUploadButtons();
        return false;
    }

    it.fileDelete = function(el, fid, id_cun, fu) {
        el.parentNode.parentNode.removeChild(el.parentNode);
        jQuery.ajax({
            url: servlet.upload2base2,
            type: 'POST',
            dataType: 'json',
            data: {
                'fid' : fid,
                'id_cun' : id_cun,
                'fu' : fu,
                'smode' : 'delete'
            }
        });
        refreshUploadButtons();
        return false;
    }

    it.closeForm = function() {
        share.frame.destroy();
        upd.run(byId(share.icon));
    }
    
    /**/it.getResponse = function() { // TODO: Не используется
        var str = jQuery('#iframe_save_data').contents().find('body').html();
        var s = str.indexOf('{');
        var f = str.lastIndexOf('}')-s+1;
        str = str.substr(s, f);
        str = jQuery.parseJSON(str);
        return str;
    }
    
    it.changeDefault = function(node, act) {
        var inp = node.getElementsByTagName('*')[0];
        var def = node.getElementsByTagName('*')[1];
        if (act) {
            if (inp.value.length == 0) {
                def.style.display = '';
            }
        } else {
            def.style.display = 'none';
            inp.focus();
        }
    }
    
    /**/it.saveImage = function(f) { // TODO: Удалить
        var ifr = byId('iframe_save_image');
        var ifrDocument = getIframeDocument(ifr);
        if (f !== undefined) {
            f.style.display = 'none';
            share.frame.setPreloader();
        }
        if (ifrDocument.getElementById('image-wrapper')) { // Загрузили форму для обрезки картинки. Надо показаться на весь экран.
            with(ifr.style) {
                position = 'absolute';
                left = top = '0px';
                height = document.body.clientHeight + 'px';
                display = '';
                width = document.body.clientWidth + 'px';
                border = 'none';
                backgroundColor = '#FFFFFF';
                zIndex = 999;
                }
            window.scrollTo(0, 0);
        } else {
            if (ifrDocument.getElementById('imageLoaded') || ifrDocument.getElementById('imageDeleted')) { // Сохранили вторую картинку или удалили изображение. Надо закрыться и обновиться.
                with(ifr.style) {
                    position = '';
                    left = top = '0px';
                    height = '0px';
                    display = 'none';
                    width = '0px';
                    border = 'none';
                    backgroundColor = '#FFFFFF';
                    zIndex = -1;
                    }
                setTimeout(function(){
                    share.frame.destroy();
                    f = undefined;
                    share.icon = undefined;
                    share.frame = undefined;
                    setTimeout(function(){
                        upd.ref();
                    }, 100);
                }, 100);
            }
        }
    }
    
    it.save = function() {
        var trs = share.form.getElementsByTagName('tr');
        var isValid = validateForm(trs);
        if (isValid) {
            //jQuery('#b-frameRoundWhite-close')[0].setAttribute('onclick', undefined);
            share.form.enc2.value = getNesting(trs, share.form.enc2.value.split(':'));
            var jf = jQuery(share.form);
            var data = {};
            var dataRaw = jf.serializeArray();
            /*var formatter = jQuery('#FORMATTER');
            if (formatter.length == 0) {
                jQuery('body').append(
                    jQuery('<div>', {
                        'id' : 'FORMATTER'
                    }));
                formatter = jQuery('#FORMATTER');
            }*/
            jf.find('input, select, textarea').attr('disabled', true);
            jQuery.each(dataRaw, function(i, el) {
                if (el.value.indexOf('<!--') > -1 || el.value.indexOf('-->') > -1 || el.value.indexOf('<script') > -1 || el.value.indexOf('</script>') > -1) {
                    data[el.name] = el.value;
                } else {
                    data[el.name] = el.value;
                /*if (browser.isIE !== 0 && browser.isIE < 9) {
                        formatter.html(el.value.replace(new RegExp('\n','g'), '{#}'));
                        data[el.name] = formatter.html().replace(new RegExp('{#}','g'), '\n');
                    } else {
                        formatter.html(el.value);
                        data[el.name] = formatter.html();
                    }*/
                }
            });
            /*formatter.remove();*/
            // Переименовываем файлы
            jQuery('#admForm .adm-multifile, #admForm .adm-file, #admForm .adm-image').each(function() {
                var fname = [], fnameold = [];
                var serv = '';
                switch (jQuery(this).attr('data-type')) {
                    case 'file':
                        serv = servlet.upload2base2;
                        break;
                    case 'multifile':
                        serv = servlet.files_upload4;
                        break;
                }
                jQuery(this).find('input[type="text"]').each(function() {
                    var jinp = jQuery(this);
                    if (jinp.attr('data-fid') !== undefined) {
                        fname['key_' + jinp.attr('data-fid')] = {
                            'id_cun' : jinp.attr('data-cun'),
                            'fu' : jinp.attr('data-fu'),
                            'fid' : jinp.attr('data-fid'),
                            'fname' : jinp.val()
                        };
                    }
                });
                jQuery(this).find('input[type="hidden"]').each(function() {
                    var jinp = jQuery(this);
                    if (jinp.attr('data-fid') !== undefined) {
                        fnameold['key_' + jinp.attr('data-fid')] = {
                            'id_cun' : jinp.attr('data-cun'),
                            'fu' : jinp.attr('data-fu'),
                            'fid' : jinp.attr('data-fid'),
                            'fname' : jinp.val()
                        };
                    }
                });
                /*console.log('fname:');
                console.dir(fname);
                console.log('fnameold:');
                console.dir(fnameold);
                console.log('Отличия:');*/
                for(var key in fname) {
                    if (fname[key].fname != fnameold[key].fname) {
                        //console.dir(fname[key]);
                        jQuery.ajax({
                            url : serv,
                            type : 'POST',
                            dataType : 'text',
                            data : fname[key],
                            success : function (resp) {
                                //console.dir(resp);
                            },
                            error: function (XMLHttpRequest, textStatus, errorThrown) {
                                alert('Ошибка переименования файла.');
                            }
                        });
                    }
                }
            });
            // Сохраняем данные
            jQuery.ajax({
                url: share.form.action,
                type: 'POST',
                dataType: 'json',
                data: data,
                success: function (resp) {
                    share.cun = resp.unit.cun;
                    if (share.upls.length > 0) {
                        runUploadFiles();
                    } else {
                        closeForm();
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    alert('Ошибка сохранения.');
                    if (console != undefined) {
                        console.log(XMLHttpRequest);
                        console.log(textStatus);
                        console.log(errorThrown);
                    }
                }
            });
            return false;
        } else {
            return false;
        }
        return isValid;
    }
    
    it.checker = function(node, state) {
        var inputs = node.getElementsByTagName('input'),
        len = inputs.length;
        for (var i = 0; i < len; i++)
            if (inputs[i].type == 'checkbox')
                inputs[i].checked = state;
        return false;
    }
    
    it.validateRequired = function(node) {
        var data = getData(node);
        if (data !== false)
            return data.length > 0;
        else
            return true;
    }
    
    it.validateInt = function(node, isRequired) {
        var res = true, value = getData(node);
        if (isRequired && checkNum(value)==false) {
            res = false;
        }
        if (!isRequired && value!='' && checkNum(value)==false) {
            res = false;
        }
        return res;
    }
    
    it.validateNum = function(node, isRequired) {
        return it.validateInt(node, isRequired);
    }
    
    it.validateDate = function(node, isRequired) {
        var res = true, value = getData(node);
        //console.log(node);
        if (isRequired && checkDate(value)==false)
            res = false;
        if (!isRequired && value!='' && checkDate(value)==false)
            res = false;
        return res;
    }
    
    it.validateTime = function(node, isRequired) {
        var res = true, value = getData(node);
        if (isRequired) {
            if (checkTime(value)==false)
                res = false;
        } else {
            if (value!='' && checkTime(value)==false)
                res = false;
        }
        return res;

        function checkTime(value) {
            if (value=='' || value.length!=5)
                return false;
            value = value.split(':');
            if (value.length==2 && value[0]<=23 && value[1]<=59)
                return true;
            else
                return false;
        }
    }
    
    it.validateSLenMax = function(node, isRequired, arg) {
        var result, len = getData(node).length;
        if (isRequired)
            result = len <= arg;
        else
            result = len > 0 ? len <= arg : true;
        return result;
    }
    
    it.validateSLenMin = function(node, isRequired, arg) {
        var result, len = getData(node).length;
        if (isRequired)
            result = len >= arg;
        else
            result = len > 0 ? len >= arg : true;
        return result;
    }
    
    it.validateNestingLimit = function(node, isRequired, arg) {
        var result, count = jQuery(node.parentNode.parentNode).find('.jquery-munrusSelector__sender li').length;
        if (isRequired)
            result = count <= arg;
        else
            result = count > 0 ? count <= arg : true;
        return result;
    }
    
    function closeForm() {
        if (typeof callback == 'function')
            callback();
        else
            it.closeForm();
    }

    function bindMultifile(container) {
        var fu = container.getAttribute('data-fu');
        var fid = container.getAttribute('data-fid');
        var upl = new plupload.Uploader({
            'runtimes' : 'flash',
            'max_file_size' : '1024mb',
            'unique_names' : false,
            'multi_selection' : true,
            'flash_swf_url' : '/files/all/plupload/js/plupload.flash.swf',
            'browse_button' : 'browse_button_plupload_' + fu,
            'url' : servlet.direct.files_upload4
        });
        upl.bind('FilesAdded', function(up, files) {
            jQuery.each(files, function(i, file) {
                jQuery(container).find('.b-files-upload__list').append(
                    jQuery('<li>', {
                        'class' : 'b-files-upload__list__item',
                        'html' : '<input id="fname_' + file.id + '" type="text" value="'+file.name+'"/>' + ' (' + plupload.formatSize(file.size) + ') ' + '<span id="progress_' + file.id + '">0%<span>'
                    }));
            });
            refreshUploadButtons();
        });
        upl.bind('UploadProgress', function(up, file) {
            jQuery('#progress_' + file.id).html(file.percent + '%');
        });
        upl.bind('BeforeUpload', function(up, file) {
            up.settings.multipart_params = {
                'id_cun' : share.cun,
                'fu' : fu,
                'fid' : fid,
                'fname' : jQuery('#fname_' + file.id)[0].value
            }
        });
        upl.bind('FileUploaded', function(up, file, response) {
            //console.log(response.response);
            });
        upl.bind('Error', function(up, args) {
            if (console !== undefined)
                console.log(args);
        });
        upl.bind('UploadComplete', function(up, files) {
            up.destroy();
            share.uploaded++;
            if (share.upls.length == share.uploaded) {
                closeForm();
            }
        });
        upl.init();
        share.upls.push(upl);
    }
    
    function bindFile(container) {
        var fu = container.getAttribute('data-fu');
        var fid = container.getAttribute('data-fid');
        var upl = new plupload.Uploader({
            'runtimes' : 'flash',
            'max_file_size' : '1024mb',
            'unique_names' : false,
            'multi_selection' : false,
            'flash_swf_url' : '/files/all/plupload/js/plupload.flash.swf',
            'browse_button' : 'browse_button_plupload_' + fu,
            'url' : servlet.direct.upload2base2
        });
        upl.bind('FilesAdded', function(up, files) {
            jQuery.each(files, function(i, file) {
                jQuery(container).find('.b-files-upload__container div').remove();
                jQuery(container).find('.b-files-upload__container').append(
                    jQuery('<div>', {
                        'class' : 'b-files-upload__file',
                        'html' : '<input id="fname_' + file.id + '" type="text" value="'+file.name+'"/>' + ' (' + plupload.formatSize(file.size) + ') ' + '<span id="progress_' + file.id + '">0%<span>'
                    }));
            });
            refreshUploadButtons();
        });
        upl.bind('UploadProgress', function(up, file) {
            jQuery('#progress_' + file.id).html(file.percent + '%');
        });
        upl.bind('Error', function(up, args) {
            //console.log(args);
            });
        upl.bind('BeforeUpload', function(up, file) {
            up.settings.multipart_params = {
                'id_cun' : share.cun,
                'fu' : fu,
                'fid' : fid,
                'fname' : jQuery('#fname_' + file.id)[0].value
            }
        });
        upl.bind('FileUploaded', function(up, file, response) {
            //console.log(response.response);
            });
        upl.bind('UploadComplete', function(up, files) {
            up.destroy();
            share.uploaded++;
            if (share.upls.length == share.uploaded) {
                closeForm();
            }
        });
        upl.init();
        share.upls.push(upl);
    }

    function runUploadFiles() {
        jQuery.each(share.upls, function(i, upl) {
            //console.log(upl);
            upl.start();
            upl.refresh();
        });
    }
    
    function refreshUploadButtons() {
        jQuery.each(share.upls, function(i, upl) {
            upl.refresh();
        });
    }

    function removeUploadButtons() {
        jQuery.each(share.upls, function(i, upl) {
            //console.log('removeUploadButtons: ' + upl.id);
            upl.destroy();
        });
    }

    function inList(val, list){
        for(var i in list)
            if(val == list[i])
                return true;
        return false;
    }
    
    function validateForm(trs) {
        var isValid = true,
        len = trs.length;
        for (var tr = 0; tr < len; tr++) {
            var subres = validateField(trs[tr]);
            isValid = isValid == false ? false : subres;
        }
        return isValid;
    }
    
    function validateField(tr) { // TODO: Протестировать валидацию во всех браузерах!!!
        var isValid = true, isRequired = false;
        var div = getElementsByClassName('adm-error', tr)[0];
        if (div !== undefined) {
            var p, ps= div.getElementsByTagName('p'), len = ps.length;
            for (p = 0; p < len; p++) { // Определяем, является ли поле обязательным
                if (isRequired) break;
                isRequired = ps[p].className.substr(6) == 'Required';
            }
            for (p = 0; p < len; p++) { // Непосредственно валидация
                var func =  it['validate'+ps[p].className.substr(6)];
                if (func !== undefined) {
                    var subres = func(ps[p], isRequired, ps[p].ondblclick());
                    ps[p].style.display = subres ? 'none' : '';
                    isValid = isValid == false ? false : subres;
                }
            }
        }
        return isValid;
    }
    
    function getNesting(trs, cur) {
        var resultTmp = [], result = [], all = [], sel = [], ns = {};
        for (var tr in trs)
            if (trs[tr].className !== undefined && trs[tr].className.substr(4) == 'nesting')
                switch (trs[tr].getAttribute('data-subtype')) {
                    case 'select':
                        ns = nestingSelect(trs[tr]);
                        //console.log(ns);
                        all = all.concat(ns.all);
                        sel = sel.concat(ns.sel);
                        break;
                    case 'checkbox':
                        ns = nestingCheckbox(trs[tr]);
                        //console.log(ns);
                        all = all.concat(ns.all);
                        sel = sel.concat(ns.sel);
                        break;
                    case 'autocomplete':
                        ns = nestingAutocomplete(trs[tr]);
                        //console.log(ns);
                        all = all.concat(ns.all);
                        sel = sel.concat(ns.sel);
                        break;
                }
        // Удаляем элементы из массива текущих связей
        var r;
        for (r in cur)
            if (inList(cur[r], all) && !inList(cur[r], sel))
                cur[r] = 0;
        resultTmp = arrUnion(cur, sel);
        r = undefined;
        for (r in resultTmp)
            if (parseInt(resultTmp[r], 10) > 0 && checkNum(resultTmp[r]) && !inList(resultTmp[r], result))
                result.push(resultTmp[r]);
        return result.join(':');
    }
    
    function nestingSelect(tr) {
        var result = {
            'all' : [], // Массив всех значений
            'sel' : [] // Массив добавленных значений
        };
        var options = tr.getElementsByTagName('select')[0],
        len = options.length;
        for (var i = 0; i < len; i++) {
            result.all.push(options[i].value);
            if (options[i].selected)
                result.sel.push(options[i].value);
        }
        return result;
    }
    
    function nestingCheckbox(tr) {
        var result = {
            'all' : [], // Массив всех значений
            'sel' : [] // Массив добавленных значений
        };
        var options = tr.getElementsByTagName('input'),
        len = options.length;
        for (var i = 0; i < len; i++) {
            result.all.push(options[i].value);
            if (options[i].checked)
                result.sel.push(options[i].value);
        }
        return result;
    }
    
    function nestingAutocomplete(tr) {
        var result = {
            'all' : [], // Массив всех значений
            'sel' : [] // Массив добавленных значений
        };
        var selected = tr.getElementsByTagName('input')[1].value.split(':');
        var oldResult = tr.getElementsByTagName('input')[2].value.split(':');
        result['all'] = result['all'].concat(selected, oldResult);
        result['sel'] = selected;
        return result;
    }
    
    function checkDate(value) {
        if (value=='' || value.length!=10)
            return false;
        value = value.split('/');
        if (value.length==3
            && !isNaN(parseInt(value[0], 10)) && value[0].length==2 && value[0]>=1 && value[0]<=31
            && !isNaN(parseInt(value[1], 10)) && value[1].length==2 && value[1]>=1 && value[1]<=12
            && !isNaN(parseInt(value[2], 10)) && value[2].length==4
                )
            return true;
        else
            return false;
    }
    
    function checkNum(value) {
        if (value=='') return false;
        var val = parseInt(value, 10)+'';
        return val!==value || isNaN(val) ? false : true;
    }
    
    function getData(el) {
        var tr = el.parentNode.parentNode.parentNode;
        var type = tr.getAttribute('data-type');
        var fu = tr.getAttribute('data-fu');
        switch (type) {
            case 'num':
                return share.form['fu_'+fu].value;
                break;
            case 'text':
                return share.form['fu_'+fu].value;
                break;
            case 'date':
                return share.form['fu_'+fu].value;
                break;
            case 'time':
                return share.form['fu_'+fu].value;
                break;
            case 'textarea':
                return share.form['fu_'+fu].value;
                break;
            case 'nesting':
                return jQuery(tr).find('.jquery-munrusSelector__sender li');
                break;
            default:
                return false;
                break;
        }
    }
    
})();
