var EBTD = EBTD || {};

/*********************************************************************************************************************
 * Registry
 *********************************************************************************************************************/
EBTD.Registry = {};

/*********************************************************************************************************************
 * Utils
 *********************************************************************************************************************/
EBTD.Utils = {};
EBTD.Utils.number_format = function( number, decimals, dec_point, thousands_sep ) {
    var i, j, kw, kd, km, minus = "";

    if(number < 0){
        minus = "-";
        number = number*-1;
    }

    if( isNaN(decimals = Math.abs(decimals)) ){
        decimals = 2;
    }
    if( dec_point == undefined ){
        dec_point = ",";
    }
    if( thousands_sep == undefined ){
        thousands_sep = ".";
    }

    i = parseInt(number = (+number || 0).toFixed(decimals)) + "";

    if( (j = i.length) > 3 ){
        j = j % 3;
    } else{
        j = 0;
    }

    km = (j ? i.substr(0, j) + thousands_sep : "");
    kw = i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands_sep);
    kd = (decimals ? dec_point + Math.abs(number - i).toFixed(decimals).replace(/-/, 0).slice(2) : "");

    return minus + km + kw + kd;
}

/*********************************************************************************************************************
 * Animate
 *********************************************************************************************************************/
EBTD.Animate = {};
EBTD.Animate.fadeInQueue = function (elements, speed,  index) {
    if(typeof(elements[index]) != 'undefined' && elements[index] != null) {
        jQuery(elements[index]).fadeIn(speed, function(){ EBTD.Animate.fadeInQueue(elements, speed, index + 1); });
    }
};


/*********************************************************************************************************************
 * Deposit
 *********************************************************************************************************************/
EBTD.Deposit = function (options) {

    var self = this;
    var groups = {};
    var currentGroup = '';
    var amount = new EBTD.Deposit.Amount();
    var form = jQuery('#depositForm');
    var lastRequest = jQuery('#depositLastRequest');

    this.getAmount = function() {
        return amount;
    }

    this.getLastRequest = function() {
        return lastRequest.val();
    }

    this.setLastRequest = function(value) {
        return lastRequest.val(value);
    }

    this.addGroup = function(group) {
        if(typeof(group) == 'object' && jQuery.inArray(typeof(group.getName()), ['string','number']) != -1) {
            groups[group.getName()] = group;
            groups[group.getName()].getSubmit().bind('click', function(e) {
                if (group.isCurrent()) {
                    return false;
                }
                self.setCurrentGroup(group.getName());
                return false;
            });
        }else{
            console.warn('EBTD.Deposit.addGroup: Unaccepted group.');
        }
    }

    this.getGroup = function(name) {
        if(typeof(groups[name]) == 'object') {
            return groups[name];
        }else{
            console.warn('EBTD.Deposit.getGroup: Undefined group with name "' + name + '".');
        }
    }

    this.setCurrentGroup = function (name) {
        if(typeof(groups[name]) == 'object') {
            jQuery.each(groups, function(index, group){
                group.unsetCurrent();
            });
            currentGroup = name;
            groups[name].setCurrent();

            if(self.getAmount().check()) {
                groups[name].calculate(self.getAmount().get());
            }else{
                groups[name].calculate(0);
            }
            self.setLastRequest(groups[name].getSubmit().val());
        }
    }

    this.getCurrentGroup = function () {
        return self.getGroup(currentGroup);
    }

    var initiate = function(options) {
        var options = jQuery.extend({}, options);

        jQuery.each(options, function(index, options) {
            var group = new EBTD.Deposit.Group(index);

            jQuery.each(options, function(index, options) {
                var method = new EBTD.Deposit.Method(index);

                jQuery.each(options, function(index, options) {
                    var mediator = new EBTD.Deposit.Mediator(index, options);
                    method.addMediator(mediator);
                });

                group.addMethod(method);
            });

            self.addGroup(group);
        });

        amount.getInput().bind('keyup change', function(event) {

            // валидация суммы оплаты
            if(self.getAmount().validate()) {
                var amount = self.getAmount().get();
                jQuery('#deposit_groups, #method_list').fadeIn();
            }else{
                var amount = 0;
            }

            // пересчитать бабло для методов и медиаторов активной группы
            self.getCurrentGroup().calculate(amount);
        });
    }

    initiate(options);
};

/**
 * Валидация формы
 */
EBTD.Deposit.Amount = function() {
    var self = this;
    var input = jQuery('#depositAmount');
    var error = jQuery('#depositAmountErrorDesc');

    input.bind('keyup keydown keypress', function(event){
        if(event.keyCode == 13) {
            return false;
        }
    });

    this.getInput = function() {
        return input;
    }

    this.get = function() {
        var value = input.val();
        if( value == undefined || value == '') {
            return '0';
        }

        return value.replace(/[,]/,'.').replace( /[\.]+$/, '');
    }

    this.set = function (value) {
        input.val( Math.ceil(parseFloat(value) * 100) / 100);
    }

    // валидация суммы пополнения
    this.check = function () {
        var value = this.get();
        var matches1 = value.match(/^[\d]+[,\.]?$/g);
        var matches2 = value.match(/^[\d]+[,\.]{1}[\d]{1,2}$/g);

        return Boolean(matches1 || matches2);
    }

    // проверка введенной суммы
    this.validate = function () {

        if(this.check() && parseFloat(this.get()) > 0) {
            input
                .removeClass('input_bgColor-red input_bgColorFocus-red')
                .addClass('input_bgColor-white input_bgColorFocus-white');

            error.hide();
            return true;
        }else{
            input
                .removeClass('input_bgColor-white input_bgColorFocus-white')
                .addClass('input_bgColor-red input_bgColorFocus-red');

            error.show();
            return false;
        }
    }
};

/**
 * Управление группой оплаты
 * @param name
 */
EBTD.Deposit.Group = function(name) {
    var self = this;
    var name = String(name);
    var submit = jQuery('#depositGroup_'+name);
    var methods = {};

    this.getName = function() {
        return name;
    }

    this.getSubmit = function() {
        return submit;
    }

    this.isCurrent = function() {
        return submit.hasClass('current');
    }

    this.setCurrent = function() {
        submit.addClass('current');
        jQuery.each(methods, function(index, method){
            method.show();
        });
    }

    this.unsetCurrent = function() {
        submit.removeClass('current');
        jQuery.each(methods, function(index, method){
            method.hide();
        });
    }

    this.addMethod = function(method) {
        if(typeof(method) == 'object' && jQuery.inArray(typeof(method.getName()), ['string','number']) != -1) {
            methods[method.getName()] = method;
        }else{
            console.warn('EBTD.Deposit.addMethod: Unaccepted method.');
        }
    }

    this.addMethods = function(methods) {
        jQuery.each(methods, function(index, method){
            self.addMethod(method);
        });
    }

    this.getMethod = function(name) {
        if(typeof(methods[name]) == 'object') {
            return methods[name];
        }else{
            console.warn('EBTD.Deposit.getMethod: Undefined method with name "' + name + '".');
        }
    }

    this.calculate = function(amount) {
        jQuery.each(methods, function(index, method) {
            method.calculate(amount);
        });
    }
};

/**
 * Управление методом оплаты
 * @param name
 */
EBTD.Deposit.Method = function(name) {
    var self = this;
    var name = String(name);
    var mediators = {};
    var currentMediator = '';
    var block = jQuery('#depositMethod_'+name);
    var submit = block.find('.methodSubmit button');
    var amount = block.find('.methodAmount');
    var mediatorSelect = block.find('.mediatorSelect');
    var mediatorSelectText = mediatorSelect.find('.mediatorSelectText');
    var mediatorList = block.find('.mediatorList');

    this.getName = function() {
        return name;
    }

    this.setAmount = function(value) {
        amount.html(value);
    }

    this.hide = function() {
        block.stop().css({opacity:'1'}).hide();
    }

    this.setMediatorSelectText = function(value) {
        mediatorSelectText.html(value);
    }

    this.setSubmitValue = function(value) {
        submit.attr('value',value);
    }

    this.show = function() {
        block.stop().css({opacity:'1'}).show();
    }

    this.addMediator = function(mediator) {
        if(typeof(mediator) == 'object' && typeof(mediator.getIndex()) == 'number') {
            mediators[mediator.getIndex()] = mediator;

            if(self.getMediatorsCount() == 1) {
                self.setCurrentMediator(mediator.getIndex());
            }

            var mediatorBlock = mediators[mediator.getIndex()].getBlock();

            if(mediatorBlock.size() > 0 && (mediatorBlock.get(0).tagName == 'BUTTON' || mediatorBlock.get(0).tagName == 'INPUT')) {
                mediatorBlock.bind('click', function(){
                    self.setCurrentMediator(mediator.getIndex());
                    return false;
                });
            }

        }else{
            console.warn('EBTD.Deposit.addMediator: Unaccepted mediator.');
        }
    }

    this.getMediator = function(index) {
        if(typeof(mediators[index]) == 'object') {
            return mediators[index];
        }else{
            console.warn('EBTD.Deposit.getMediator: Undefined mediator with index "' + index + '".');
        }
    }

    this.setCurrentMediator = function (index) {
        if(typeof(mediators[index]) == 'object') {

            currentMediator = index;
            var mediator    = self.getCurrentMediator();
            var amount      = mediator.getAmount();
            var title       = mediator.getTitle();
            var value       = mediator.getValue();

            self.hideMediatorList();

            if(typeof(title) == 'string') {
                self.setMediatorSelectText(title);
            }

            if(typeof(amount) == 'string') {
                self.setAmount(amount);
            }

            if(typeof(value) == 'string') {
                self.setSubmitValue(value);
            }
        }
    }

    this.getCurrentMediator = function () {
        return self.getMediator(currentMediator);
    }

    this.getMediatorsCount = function() {
        return Object.keys(mediators).size();
    }

    this.calculate = function(amount) {
        jQuery.each(mediators, function(index, mediator) {
            mediator.calculate(amount);
        });

        var mediator = self.getCurrentMediator();

        if(typeof(mediator) == 'object') {
            self.setAmount(mediator.getAmount());
        }
    }

    this.showMediatorList = function() {
        jQuery('.mediatorSelect.active').removeClass('active');
        jQuery('.mediatorList').hide();

        mediatorSelect.addClass('active');
        mediatorList.slideDown(150);
    }

    this.hideMediatorList = function() {
        mediatorSelect.removeClass('active');
        mediatorList.hide();
    }

    mediatorSelect.bind('click', function() {
        if(mediatorSelect.hasClass('active')) {
            self.hideMediatorList();
        }else{
            self.showMediatorList();
        }
        return false;
    });

    jQuery('body, #deposit .group').bind('click', function(){
        self.hideMediatorList();
    });

    mediatorList.bind('click', function(e){
        e.stopPropagation();
    });
};

/**
 * Управление посредником
 * @param index
 * @param options
 */
EBTD.Deposit.Mediator = function(index, options) {
    var self    = this;
    var index   = parseInt(index);
    var rate    = new EBTD.Deposit.Rate(options);
    var block   = jQuery('#depositMediator_'+index);
    var amount  = block.find('.mediatorAmount').first();
    var title   = block.find('.mediatorTitleText').first();
    var desc    = block.find('.mediatorDescription').first();
    var label   = null;

    this.getBlock = function(){
        return block;
    }

    this.getIndex = function() {
        return index;
    }

    this.getRate = function() {
        return rate;
    }

    this.getAmount = function() {
        return label;
    }

    this.setAmount = function(value) {
        label = value;
        amount.html(label);
    }

    this.getTitle = function() {
        return title.html();
    }

    this.getValue = function() {
        return block.attr('value');
    }

    this.getDesc = function() {
        return desc.html();
    }

    this.calculate = function(amount) {

        if(typeof(rate) == 'object') {
            var value = rate.calculate(amount);

            if(value > 0) {
                self.setAmount( rate.getPrefix() + ' ' + EBTD.Utils.number_format(value, 0, ',', ' ') + ' ' + rate.getSign() );
            }else{
                self.setAmount( EBTD.Utils.number_format(value, 0, ',', ' ') + ' ' + rate.getSign() );
            }
        }
    }
};

/**
 * Управление курсом валюты
 * @param options
 */
EBTD.Deposit.Rate = function(options) {
    var _options = {
        'sign'                  : '$',
        'rate'                  : 1,
        'commissionPercent'     : 0,
        'addCommissionAmount'   : 0,
        'minCommissionAmount'   : 0,
        'maxCommissionAmount'   : 0,
        'prefix'                : ''
    };

    if(options) {
        jQuery.extend(_options, options);
    }

    this.calculate = function( amount ) {

        if(parseFloat(amount) == 0) {
            return 0;
        }

        amount = parseFloat( amount ) * parseFloat(_options.rate);

        var minCommission = parseFloat(_options.minCommissionAmount);
        var maxCommission = parseFloat(_options.maxCommissionAmount);
        var addCommission = parseFloat(_options.addCommissionAmount);
        var commission = amount * parseFloat( _options.commissionPercent );

        if( minCommission > 0 && commission < minCommission) {
            commission = minCommission;
        }
        if( maxCommission > 0 && commission > maxCommission) {
            commission = maxCommission;
        }

        return Math.ceil( (amount + commission + addCommission) * 100 ) / 100;
    };

    this.getSign = function() {
        return _options.sign;
    }

    this.getPrefix = function() {
        return _options.prefix;
    }

    this.getOptions = function() {
        return _options;
    }
}
