function showError(id, error) {
    if ($('#' + id + '-error')) {
        $('#' + id + '-error').show();
        $('#' + id + '-error').text(error);
        $('#' + id + '-error').parent().addClass('err');
    }
}

function isEmpty(field) {
    if ($('#' + field).length === 0 || $('#' + field).val() === '') {
        return true;
    } else {
        return false;
    }
}

function doValidation() {
    var errors = false;
    for (i = 0; i < fields.length; i++) {
        var field = fields[i];
        $('#' + field + '-error').hide();
        $('#' + field + '-error').parent().removeClass('err');
        if (fields_require[field] && isEmpty(field)) {
            showError(field, empty_error);
            errors = true;
        } else if (typeof(templates[field]) != 'undefined') {
            var reg = new RegExp(templates[field], 'i');
            if (!reg.test($('#' + field).val())) {
                showError(field, fields_error[field]);
                errors = true;
            }
        }
    }
    return errors;
}

var Popup = function(options) {this.init(options);};
Popup.prototype = {
    element: null,
    content: null,
    wrapId: 'wrap',
    openTriggers: undefined,
    closeTriggers: undefined,
    onClose: null,
    onHide: null,
    id: null,
    firstInput: null,
    shadow: null,
    init: function(options) {
        $.extend(true, this, options);

        //init popup element
        if (null !== this.element && 'object' == typeof(this.element) && 'function' == typeof(this.element.attr)) {
            //create popup from html-element
            if (null === (this.id = this.element.attr('id'))) {
                this.genId();
                this.element.attr('id', this.id);
            }
        } else if (null !== this.content) {
            //create popup dynamically
            var html = '<div id="' + this.genId() + '" class="popup" style="display:none;">' +
                        '<div class="top"></div>' +
                        '<div class="inner">' +
                        this.content +
                        '</div>' +
                        '<a class="close" href="#"><?=_("close")?></a>' +
                        '<div class="bottom"></div>' +
                        '</div>';
            $('body').append(html);
            this.element = $('#' + this.id);
        } else {
            alert("Can't create popup: bad element.");
            return false;
        }

        //triggers
        $(this.openTriggers).click($.proxy(function(event) {
            this.show();
            event.stopPropagation();
        }, this));

        if (this.closeTriggers == undefined) {
            this.closeTriggers = $('#' + this.id + ' a.close');
        }

        this.closeTriggers.click($.proxy(function(event){
            this.close();
            event.stopPropagation();
        }, this));

        //other
        this.firstInput = $('#' + this.id + ' input').first();
        this.firstInput = (undefined === this.firstInput) ? null : this.firstInput;
        this.shadowInit();
    },
    show: function() {
        this.shadowShow();
        this.element.show();
        if (null !== this.firstInput) {
            if (this.firstInput.css('display') != '') {
                this.firstInput.focus();
            }
        }
        $(document).keydown($.proxy(this.keyDown, this));
    },
    hide: function () {
        this.element.hide();
        this.shadowHide();
        $(document).keydown(null);

        if ('function' == typeof(this.onHide)) {
            this.onHide();
        }
    },
    close: function () {
        this.hide();
        if ('function' == typeof(this.onClose)) {
            this.onClose();
        }
    },
    keyDown: function(event) {
        var key = event.which || event.keyCode;
        if (key == 27) { // ESC
            this.hide();
        }
    },
    shadowInit: function() {
        if (null !== this.shadow) {
            return;
        }
        $('body').append('<div id="' + this.id + '-shadow" class="shadow" style="display:none;"></div>');
        this.shadow = $('#' + this.id + '-shadow');
        this.shadow.click($.proxy(function() {this.hide()}, this));
    },
    shadowShow: function() {
        if (null === this.shadow) {
            this.shadowInit();
        }
        this.shadow.css('height', $('#' + this.wrapId).height() + 'px').css('display', 'block');

    },
    shadowHide: function() {
        if (null === this.shadow) {
            this.shadowInit();
        }
        this.shadow.hide();
    },
    genId: function() {
        this.id = 'popup-auto-' + Math.round(Math.random() * 10000);
        return this.id;
    }
};

var Tooltips = function(options) {Tooltips.prototype.init(options);};
Tooltips.prototype = {
    name: 'tooltip',
    selector: null,
    tip: null,
    tipInner: null,
    width: 120,
    offsetLeft: 15,
    offsetTop: 27,
    space2Br: false,
    init: function(options) {
        this.selector = ('undefined' != typeof(options.selector)) ? options.selector : this.selector;
        this.space2Br = ('undefined' != typeof(options.space2Br)) ? options.space2Br : this.space2Br;
        this.width = ('undefined' != typeof(options.width)) ? options.width : this.width;

        this.insertHtml();

        $(this.selector).hover(
            $.proxy(function(event){
                var element = $(event.target);
                //var offset = element.Offset();
                var offset = {left: event.pageX, top: event.pageY};
                this.tipInner.html((this.space2Br) ? element.attr('title').replace(/, /g, ',<br />') : element.attr('title'));
                element.attr('title', '');
                this.tip.css({display: 'block', left: offset.left - this.offsetLeft + 'px', top: offset.top + this.offsetTop + 'px'});
            }, this),
            $.proxy(function(event){
                var element = $(event.target);
                element.attr('title', (this.space2Br) ? this.tipInner.html().replace(/,<.*?>/g, ', ') : this.tipInner.html());
                this.tip.css({display: 'none'});
            }, this)
        );

    },
    insertHtml: function() {
        if (null !== this.tip) { return; }
        $('body').append('<div id="tooltip-container" class="tooltip" style="display:none;width:' + this.width + 'px"><div class="pointer"></div><div class="inner"></div></div>');
        this.tip = $('#tooltip-container');
        this.tipInner = $('#tooltip-container .inner').first();
    }
};

var Krutilka = function(options) {this.init(options);};
Krutilka.prototype = {
    id: undefined,
    $container: undefined,
    $loader: undefined,
    showRequestCount:0,
    init: function(options) {
        if ($.isPlainObject(options)) {
            $.each(options, $.proxy(function(key, val){
                this[key] = val;
            }, this));
        }
        this.id = 'ajax-loader-' + Math.round(Math.random() * 10000);
        this.$container = (this.$container === undefined) ? $('body') : this.$container;
    },
    draw: function() {
        this.$container.append('<div id="' + this.id + '" class="ajax-loader-fixed"></div>');
        this.$loader = $('#' + this.id).height(this.getContainerHeight());
        if (this.$container.is('body')) {
            this.$loader.css('top', this.$container.scrollTop());
        }
        this.showRequestCount = 0;
    },
    getContainerHeight: function() {
        return this.$container.is('body') ? $(window).height() : this.$container.height();
    },
    show: function(){
        if (this.id !== $('#' + this.id, this.$container).attr('id')) {
            this.draw();
        }
        this.showRequestCount++;
        if (this.showRequestCount == 1) {
            this.$loader.css('display', 'block').height(this.getContainerHeight()).focus();
        }
    },
    hide: function(){
        if (this.showRequestCount > 1) {
            this.showRequestCount--;
        } else if (this.showRequestCount > 0) {
            this.showRequestCount = 0;
            this.$loader.css('display', 'none');
        }
    }
};

