var bff =
{

extend: function(destination, source) {
    for (var property in source)
        destination.prototype[property] = source[property];
    return destination;
},

addListener: function (element, event, func)
{   
    var handler = function (e)
    {
        var target = e.target || e.srcElement;
        var e = e || window.event;
        func.call(bff.ie ? target : this, e)
    };
    
    bff.ie ? element.attachEvent('on' + event, handler) : element.addEventListener(event, handler, false);
},

cancelEvent: function(event) {
  var e = event.originalEvent || event;
  if (e.preventDefault)
      e.preventDefault();
  if (e.stopPropagation) 
      e.stopPropagation(); 
  e.cancelBubble = true;
  e.returnValue = false;
  return false;
},

isEmail: function(item)
{
    var at="@";
    var dot=".";
    var lat=item.indexOf(at);
    var litem=item.length;
    var ldot=item.indexOf(dot);

       var regx= new RegExp ("^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[-0-9a-z_^\\.]+\\.[a-z]{2,6}$", 'i');
       if (!regx.test(item)) {
               return false;
       }
    if (item.indexOf(at)==-1) return false;
    if (item.indexOf(at)==-1 || item.indexOf(at)==0 || item.indexOf(at)==litem) return false;
    if (item.indexOf(dot)==-1 || item.indexOf(dot)==0 || item.indexOf(dot) >= litem - 2) return false;
    if (item.indexOf(at,(lat+1))!=-1) return false;
    if (item.substring(lat-1,lat)==dot || item.substring(lat+1,lat+2)==dot) return false;
    if (item.indexOf(dot,(lat+2))==-1) return false;
    if (item.indexOf(" ")!=-1)  return false;

    return true;
},

textLimit: function(ta, count, counter) 
{
  var text = document.getElementById(ta);
  if(text.value.length > count) {
    text.value = text.value.substring(0,count);
  }
  if(arguments.length>2) { // id of counter is defined
    document.getElementById(arguments[2]).value = text.value.length;
  }
},

textInsert: function(fieldID, text, pos) 
{
    var field = document.getElementById(fieldID);

    // если opera, то не передаем фокус
    if(navigator.userAgent.indexOf('Opera')==-1) { field.focus(); }
    
    if(document.selection){ //ie
        document.selection.createRange().text = text + ' ';
    }
    else if (field.selectionStart || field.selectionStart == 0) 
    {
        var strFirst = field.value.substring(0, field.selectionStart);
        field.value = strFirst + text + field.value.substring(field.selectionEnd, field.value.length);

        // ставим курсор
        if(!pos){
            var pos = (strFirst.length + text.length);
            field.selectionStart = field.selectionEnd = pos;
        } else {
            field.selectionStart = field.selectionEnd = (strFirst.length + pos);
        }
    } 
    else {
        field.value += text;
    } 
},

popupPic: function(sPicURL) 
{ 
    window.open( "/popup.htm?"+sPicURL, "", "resizable=1, scrollbars=yes, HEIGHT=200,WIDTH=200"); 
},

busylayer: function( toggle, callback )
{
    callback = callback || new Function();
    toggle = toggle || false; 
    
    var bl = $('#busyLayer');
    if(!bl.length) //if not exists
    {
        var body = document.getElementsByTagName('body')[0];

        bl = document.createElement('div');
        bl.id = 'busyLayer';
        bl.className = 'busyLayer';
        bl.style.display = 'none';
        bl.style.textAlign = 'center';
        bl.innerHTML = '<img src="/img/progress-large.gif" />';       
        body.appendChild(bl); 

        $(document).keydown(function(e) {
            if (e.keyCode == 27 && $(bl).is(':visible')) { 
                bff.cancelEvent(e);
                $(bl).fadeOut(500); 
            }
        });
    }
    bl = $(bl);

    if(bl.is(':visible')) {
        if(toggle){
            bl.fadeOut(500);
        }
        return;
    }
    
    var height = $(document).height();
    var paddingTop = (height/2);
    bl.css('height', height + 'px');
    bl.css('paddingTop', paddingTop + 'px'); 
    bl.fadeIn(600, callback);
},

ajax: function(url, params, callback)
{
    var bffAjxProcessErrors = function(errors, system){
        if(system) {
             console.log(errors);
        } else {
            var err = '';  
            for(i in errors)
                err += errors[i]['msg'] + '<br/>';
            utils.popupError(err); 
        }
    };                             
    
    $.ajax({
        url: url, data: params, dataType: 'json', type: 'POST',
        success: function(responseData) {
            if(responseData.errors.length)
                bffAjxProcessErrors(responseData.errors, false);
                
            if(callback) callback(responseData.data);
        },
        error: function(xhr, status, e){  
            bffAjxProcessErrors(e, true);
            if(callback) callback(false);
        }
        });
},

ajaxToggleWorking: false,
ajaxToggle: function(nRecordID, sURL, _options)
{
    
    if(bff.ajaxToggleWorking)
        return;
    
    bff.ajaxToggleWorking = true;
    
    var options = { };
        options = $.extend({
            link: '#lnk_',
            block: 'block', unblock: 'unblock',
            action: 'cf-toggle',
            progress: false,
            toggled: false //return toggled records ids 
        }, _options || {});
    if(sURL == '' || sURL == undefined)
        return;
    
    if(options.progress)
        $(options.progress).show();
    
    var eLink = null;
    bff.ajax(sURL, {'rec': nRecordID, 'toggled': options.toggled , 'action':options.action }, 
        function(data) {
            if(data) {
                if(options.toggled)
                {
                   data.toggled.each( function(t){
                        eLink = $(options.link+t); 
                        if( eLink!=undefined) {
                            eLink.removeClass( (result.status ? options.block : options.unblock) );
                            eLink.addClass( (result.status ? options.unblock : options.block) );
                        }   
                   });
                }
                else {
                    eLink = $(options.link+nRecordID);
                    if( eLink!=undefined) {
                        var has = eLink.hasClass( options.unblock);
                        eLink.removeClass( (has? options.unblock : options.block) );
                        eLink.addClass( (has? options.block : options.unblock) ); 
                    }
                }
            } 
             
            if(options.progress)
                $(options.progress).hide();
            
            bff.ajaxToggleWorking = false; 
        }
    );
},

ajaxDeleteWorking: false,
ajaxDelete: function(sQuestion, nRecordID, sURL, _options)
{
    if(bff.ajaxDeleteWorking)
        return;

    if(sQuestion!=false)
        if(!confirm(sQuestion))
            return;
    
    bff.ajaxDeleteWorking = true;

    var options = {};
        options = $.extend({
            prefix: '#item_',
            paramKey: 'rec',
            progress: false
        }, _options || {});
    
    if(sURL == '' || sURL == undefined)
        return;
    
    if(options.progress)
        $(options.progress).show();
    
    var params = {}; params[options.paramKey] = nRecordID;
    bff.ajax(sURL, params, function(data) {
            
        if(options.progress)
            $(options.progress).hide();
        
        if(data){
            //$(options.prefix+nRecordID).slideUp('slow', function(){
//                       $(this).remove();
//                    });
           $(options.prefix+nRecordID).remove();
        }
        
        bff.ajaxDeleteWorking = false;
   });
},
    
rotate_tableDnD: function(list, url, rotateClass, progress)
{
    var aOldOrder = Array();
    var aNewOrder = Array();
    var rows      = Array(); 
    var orderChanged = 0;
    var progress     = $(progress);
    
    $(list).tableDnD
    (
        {    
            onDragClass: rotateClass,
            onDragStart: function(table, row)
            {
                rows = table.tBodies[0].rows;
                for(var i=0; i<rows.length; i++)
                {
                    aOldOrder[i] = rows[i].id.replace('tr', '');
                }
            },
            onDrop: function(table, row)
            {   
                rows = table.tBodies[0].rows;
                orderChanged = 0;                 
                for (i=0; i<rows.length; i++)
                    aNewOrder[i] = rows[i].id.replace('tr', '');
                for(i=0; i<aOldOrder.length; i++) 
                {
                    if(aOldOrder[i] != aNewOrder[i])
                    {
                       orderChanged = 1; 
                       break;
                    }
                }
                if(orderChanged == 1)
                {    
                    progress.show();
                    $.ajax({
                      type: 'POST',
                      url: url,
                      data: $.tableDnD.serialize(),  
                      success: function(data) { 
                            var tbl = $(list+' tr');
                            for(var i=0;i<tbl.length;i++)
                            {
                                $(tbl[i]).attr('class','row'+(i%2));   
                            }
                          
                          progress.hide(); }
                    });
                }
            }
        }
    );
},

formSelects: 
{
    MoveAll: function(source_id, destination_id)
    {
        var source      = document.getElementById(source_id);
        var destination = document.getElementById(destination_id);
        
        for(var i=0; i<source.options.length; i++)
        {
            var opt = new Option(source.options[i].text, source.options[i].value, false);
            opt.style.color = source.options[i].style.color;
            destination.options.add(opt);
        }
        source.options.length = 0;
    },

    MoveSelect: function (source_id, destination_id)
    {
        var source      = document.getElementById(source_id);
        var destination = document.getElementById(destination_id);
        
        for(var i=source.options.length-1; i>=0; i--)
        {
            if(source.options[i].selected==true)
            {
                var opt = new Option(source.options[i].text, source.options[i].value, false);
                opt.style.color = source.options[i].style.color;
                destination.options.add(opt);
                source.options[i] = null;
            }
        }  
    },

    SelectAll: function(sel_id)
    {
        var sel = document.getElementById(sel_id);
        for(i=0; i<sel.options.length; i++)
        {
            sel.options[i].selected = true;
        }     
    }
},    

accordionMenu: function(selector, current) 
{
    $(document).ready(function(){

        current = current || 0;
        
        //hide all
//        $(selector+' ul').each(function(){
//            this.style.overflow = 'hidden';
//            this.style.visibility = 'hidden';
//            this.style.height = '0px'; 
//        });
        
        //show current 
        
        current = $(selector+' li.tab:eq('+current+') ul'); 
        
        if(current.length) {   
            current.height( current[0].scrollHeight + 'px' );  
            current.css('visibility', 'visible');
        }
        
        $(selector+' li a.tab').click(function(){
             var nxt = $(this).next();
             if(nxt.is('ul'))
             {   
                if(!nxt.is(':hidden')) {
                    nxt.animate({'height': '0px', 'opacity': 0}, 380);
                }
                else {     
                    nxt.css('visibility', 'visible');
                    nxt.animate({'height': (nxt[0].scrollHeight+'px'), 'opacity': 1 }, 380);
                    if(nxt.attr('id')!=current.attr('id')) 
                    {
                        current.animate({'height': '0px', 'opacity': 0}, 380);  
                        current = nxt;
                    }
                }
                return false;                                  
             }
             
        });

    });
},

accordionFEMenu: function(selector, current) 
{
    $(document).ready(function(){

        current = current || 0;
        //$(selector+' ul').each(function(){
//            this.style.overflow = 'hidden';
//            this.style.visibility = 'hidden';
//            this.style.height = '0px'; 
//            this.style.margin = '0px'; 
//        });
        
       // current = $(selector+' div.button').next('ul.productList:eq('+current+')');
//        
//        if(current.length) {   
//            current.height( current[0].scrollHeight + 'px' );  
//            current.css('visibility', 'visible');
//        }
        
        $(selector+' div.button').click(function(){
            //hide all
            $(selector+' ul').animate({'height': 0, 'opacity': 0}, 380);
            
             var nxt = $(this).next();
             if(nxt.is('ul'))
             {   
                if(!nxt.is(':hidden')) {
                    nxt.animate({'height': '0px', 'opacity': 0}, 380);
                }
                else {     
                    nxt.css('visibility', 'visible');
                    nxt.animate({'height': (nxt[0].scrollHeight+'px'), 'opacity': 1 }, 380);
//                    if(nxt.attr('id')!=current.attr('id')) 
//                    {
//                        current.animate({'height': '0px', 'opacity': 0}, 380);  
//                        current = nxt;
//                    }
                }
                return false;                                  
             }
        });

    });
},

formChecker: function(form,options){
    $(document).ready(function(){
        this.initialize(form,options);     
    }.bind(this));
}

};

/*@cc_on bff.ie=true;@*/ 

bff.formChecker.prototype = 
{
    initialize: function(form, options)
    {
        this.form = $(form);
        this.options  = { 
            scroll: false, 
            errorMessage: true, errorMessageBlock: '#error_block', errorMessageText: '#error_msg',  
            password: '#password', passwordNotEqLogin: true, passwordMinLength: 3, 
            login: '#login', loginMinLength: 5};
        
        if(options) {
            for (var o in options) {
                this.options[o] = options[o];
            }
        }
        
        //init error message
        if(this.options.errorMessage){
            this.errorMessageBlock = $(this.options.errorMessageBlock);
            this.errorMessageText  = $(this.options.errorMessageText);
        }
        
        this.submit_btn = this.form.find('input:submit');
        this.next_btn = this.form.find('.next');
        this.required_fields = this.form.find('.required');
        
        //attach events
        var f = function(){ return this.check(); }.bind(this);
        this.form.submit(f);
        this.required_fields.bind('blur keyup change', $.debounce(f, 400));
        
        this.check();
    },

    showMessage: function( text ){
        if(this.options.errorMessage) {
            this.errorMessageText.html(text); 
            if(!this.errorMessageBlock.is(':visible'))     
                this.errorMessageBlock.slideDown();
            
            this.errorMessageShowed = true; 
            
            if(this.options.scroll)
                $.scrollTo(this.options.errorMessageBlock, this.options.scroll); 
        }
    },  
    
    check: function(focus){ 
        this.errorMessageShowed = false;   
        var ok_fields = 0;
        var me = this;
        this.required_fields.each(function() {
            var obj = $(this), fld = obj.find('input:visible, textarea:visible, select:visible'), result = false;
            
            if(!fld.length) {
                result = 1;
            }
            else {
                if(obj.is('.check-email')){
                    result = me.checkEmail(fld);
                }
                else if(obj.is('.check-password')){
                    result = me.checkPassword(fld);
                }
                else if(obj.is('.check-login')){
                    result = me.checkLogin(fld);
                }
                else if(obj.is('.check-select')){
                    result = me.checkSelect(fld);
                }
                else if(obj.is('.check-digits')){
                    result = me.checkDigits(fld);
                }
                else if(obj.is('.check-latin')){
                    result = me.checkLatin(fld);
                }
                else if(obj.is('.check-anum')){
                    result = me.checkANum(fld);
                }
                else if(obj.is('.check-anumdelim')){
                    result = me.checkANumDelim(fld);
                }
                else{
                    result = me.checkEmpty(fld);
                }
            }
            if(result)
                obj.removeClass('clr-error');
            else {
                obj.addClass('clr-error');
                if(focus) fld.focus();
            }

            if(!result) return false;
            ok_fields += Number(result);  
        });

        var is_ok = (ok_fields == this.required_fields.length);
        if(is_ok && this.additionalCheck) {
            is_ok = this.additionalCheck();
        }
        
        if(this.options.errorMessage && !this.errorMessageShowed)
            this.errorMessageBlock.slideUp(); 

        if(this.afterCheck)
            this.afterCheck();
        this.next_btn.attr('disabled', !is_ok);    
            
        this.submit_btn.attr('disabled', !is_ok);
        return is_ok;
    },

    checkSelect: function(fld){                                 
        return parseInt(fld.val())!=0;
    },
    
    checkEmpty: function(fld){  
        return Boolean($.trim( fld.val() ));
    },

    checkLogin: function(fld){
        if(!this.checkEmpty(fld)) {
            return false;
        }

        var login = fld.val();
        if(login.length < this.options.loginMinLength) {
            this.showMessage('<b>логин</b> слишком короткий');  
            return false;
        }     
        
        var re = /^[a-zA-Z0-9_]*$/i;
        if(!re.test(login)) {
            this.showMessage('<b>логин</b> должен содержать только латиницу и цифры');  
            return false;
        }
        return true;
    },
    
    checkPassword: function(fld){
        if(!this.checkEmpty(fld)) {
            return false;
        }

        var pass = fld.val();
                
        if(fld.hasClass('check-password2'))
        {
            if(pass != $(this.options.password).val()) {
                this.showMessage('<b>подтверждения пароля</b>');  
                return false;
            }
            return true;
        }
        if(pass.length < this.options.passwordMinLength) {
            this.showMessage('<b>пароль</b> слишком короткий');  
            return false;
        }                
        if(this.options.passwordNotEqLogin && this.options.hasOwnProperty('login') && 
           (pass == this.options.login || pass == $(this.options.login).val() ) ) {
            this.showMessage('<b>логин</b> и <b>пароль</b> не должны совпадать');  
            return false;
        }
        return true;
    },
    
    checkEmail: function(fld){
        var re = /^\s*[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\s*$/i;
        if(this.checkEmpty(fld)) {
            var is_correct = re.test(fld.val());
            if(is_correct)
                fld.removeClass('clr-error');
            else
                fld.addClass('clr-error');

            return is_correct;
        }
        return false;
    },
    checkDigits: function(fld){
         if(!this.checkEmpty(fld)) {
            return false;
        }
        var re = /^[0-9-]*$/i;
        if(!re.test(fld.val())) {
            this.showMessage('<b>поле</b> может содержать только цифры и знак (-)');  
            return false;
        }
        return true;
    },
    checkANum: function(fld){
         if(!this.checkEmpty(fld)) {
            return false;
        }
        var re = /^[\w]+$/i;
        if(!re.test(fld.val())) {
            this.showMessage('<b>поле</b> должно содержать только буквы и цифры ');  
            return false;
        }
        return true;
    },
    checkANumDelim: function(fld){
         if(!this.checkEmpty(fld)) {
            return false;
        }
        var re = /^[\w_\+\. \-\[\]]+$/i;
        if(!re.test(fld.val())) {
            this.showMessage('<b>поле</b> должно содержать только буквы, цифры и разделители');  
            return false;
        }
        return true;
    },
    checkLatin: function(fld){
         if(!this.checkEmpty(fld)) {
            return false;
        }
        var re = /^[a-zA-Z_0-9]*$/i;
        if(!re.test(fld.val())) {
            this.showMessage('<b>поле</b> может содержать только буквы латинского алфавита, символ "_" и цифры');  
            return false;
        }
        return true;
    }
};
