(function() {
    
$(document).ready(function() 
{
    $.extend($.ui.dialog.prototype.options, {
        modal: true,
        resizable: false
    });

    Tools.prepareDatePicker();
    Tools.prepareInputDefaultValue();
    Tools.prepareTooltip();
    
    if (!$.browser.msie) {
        
        // ресайзим левую полосу
        if ($('#main-sidebar').length) {
            var _winResizeTimeout = null;
            $(window).bind('resize load', function() {
                clearTimeout(_winResizeTimeout);
                _winResizeTimeout = setTimeout(function() {
                    var blocks = $('#main-sidebar div.sb-float-resize');
                    if ($('#main-sidebar')[0].offsetWidth < 300) {
                        blocks.addClass('sb-float-maxsize');
                    } else {
                        blocks.removeClass('sb-float-maxsize');
                    }
                }, 300);
            });
        }
    }
});


IndividualBookingForm = {

    show: function(managerId, tourId)
    {
        $('#individual-booking-dialog').remove();
        
        var _dialog = $('<div id="individual-booking-dialog"></div>').dialog({
            title: 'Экспресс-заказ',
            height:  580,
            width: 550,
            buttons: {
                'Отправить сообщение': function() {
                	// или телефон или email
                	if(!$('form :input[name=email]', _dialog).val() && $('form :input[name=phone]', _dialog).val()) $('form :input[name=email]', _dialog).attr('notrequired', 'true');
                	if($('form :input[name=email]', _dialog).val() && !$('form :input[name=phone]', _dialog).val()) $('form :input[name=phone]', _dialog).attr('notrequired', 'true');
                	
                    if (!$('form :input', _dialog).validate()) return;
                    
                    var _params          		= $('form', _dialog).serializeHash();
                    _params['managerId'] 		= managerId || null;
                    _params['tourId']  		    = tourId    || null;
                    _params['url']       		= window.location.href;
                    _params['createPreorder'] 	= true;
                    
                    $.jsHttpRequest({
                        url: '/site/booking/send-simple-booking-form',
                        data: _params,
                        target: _dialog,
                        onReady: function(result, text) {
                            if (text) return _dialog.html(text);
                            _dialog.html('<div class="result-ok" style="margin: 20px 0;">Сообщение успешно отправлено</div>');
                            _dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        }
                    });
                }
            } 
        });
        
        $.jsHttpRequest({
            url: '/site/booking/simple-booking-form',
            cache: false,
            data: {  },
            onReady: function(result, text) {
                _dialog.html(text);
                Tools.prepareInputDefaultValue(_dialog);
            }
        });
    },
    
    showControlQuality: function()
    {
        $('#individual-booking-dialog').remove();
        
        var _dialog = $('<div id="individual-booking-dialog"></div>').dialog({
            title: 'Форма обратной связи',
            height: 440,
            width: 550,
            buttons: {
                'Отправить сообщение': function() {
                    
                	// или телефон или email
                	if(!$('form :input[name=email]', _dialog).val() && $('form :input[name=phone]', _dialog).val()) $('form :input[name=email]', _dialog).attr('notrequired', 'true');
                	if($('form :input[name=email]', _dialog).val() && !$('form :input[name=phone]', _dialog).val()) $('form :input[name=phone]', _dialog).attr('notrequired', 'true');
                	
                    if (!$('form :input', _dialog).validate()) return;
                    
                    var _params          = $('form', _dialog).serializeHash();
                    console.log(_params);
                    $.jsHttpRequest({
                        url: '/site/booking/send-quality-control',
                        data: _params,
                        target: _dialog,
                        onReady: function(result, text) {
                            if (text) return _dialog.html(text);
                            _dialog.html('<div class="result-ok" style="margin: 20px 0;">Сообщение успешно отправлено</div>');
                            _dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        }
                    });
                }
            } 
        });
        
        $.jsHttpRequest({
            url: '/site/booking/quality-control-form',
            cache: false,
            data: {  },
            onReady: function(result, text) {
                _dialog.html(text);
                Tools.prepareInputDefaultValue(_dialog);
            }
        });
    }
}

ActualOffer = 
{
    showForm: function(type, offerId, objectId, url, title)
    {
        $('#actual-offer-edit-form').remove();
        var _dialog = $('<div id="actual-offer-edit-form"></div>').dialog({
            title: 'Актуальное предложение',
            height: 350,
            width: 550
        });
        
        var _buttons = {
            'Сохранить': function() {
                if (!$('form :input', _dialog).validate()) return;
                
                var _params = $('form', _dialog).serializeHash();
                _params['isSave'] = 1;
                
                $.jsHttpRequest({
                    url: '/site/spo/edit-actual-offer',
                    data: _params,
                    target: _dialog,
                    onReady: function(result, text) {
                        if (text) return _dialog.html(text);
                        _dialog.html('<div class="result-ok" style="margin: 20px 0;">Сохранено</div>');
                        _dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        setTimeout(window.location.reload, 1000);
                    }
                });
            }
        };
        
        if (offerId) {
            _buttons['Удалить'] = function() {
                $.jsHttpRequest({
                    url: '/site/spo/edit-actual-offer',
                    data: { 'isRemove': 1, 'offer': { 'id': offerId } },
                    target: _dialog,
                    onReady: function(result, text) {
                        if (text) return _dialog.html(text);
                        _dialog.html('<div class="result-ok" style="margin: 20px 0;">Удалено</div>');
                        _dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        setTimeout(window.location.reload, 1000);
                    }
                });
            }
        }
        
        _dialog.dialog('option', 'buttons', _buttons);
        
        $.jsHttpRequest({
            url: '/site/spo/edit-actual-offer',
            cache: false,
            data: { 'offer': { 'id': offerId, 'type': type, 'objectId': objectId, 'url': url || window.location.href, 'title': title } },
            onReady: function(result, text) {
                _dialog.html(text);
                Tools.prepareDatePicker(_dialog);
            }
        });
    }
}

TourCompare = {
    
    compare: function(elem)
    {
        var checkedItems = $('input.select-table-row:checked');
        if (checkedItems.size()) {
            var compare = '';
            $.each(checkedItems, function() {
                compare += $(this).val() + '-';
            });
            compare = compare.substr(0, compare.length - 1);
            Tools.popup(elem.href +'/'+ compare + '/?popup=1', 'height=650,width=900,location=1');
        } else {
            alert('Не выбрано ни одного тура для сравнения!');
        }
    },
    
    remove: function(elem)
    {
        var box = $(elem).parents('.item:first');
        $.jsHttpRequest({
            url: '/site/index/remove-from-compare',
            data: { 'compare': $(elem).attr('compare') },
            target: box,
            onReady: function(result, text) {
                box.slideUp();
            }
        });      
    },
    
    save: function(_btn)
    {
        var fields = $(_btn).siblings(':input');
        if (!fields.validate()) return false;
        $(_btn).attr('disabled', 'disabled');
        $.jsHttpRequest({
            url: '/site/index/save-compare',
            data: $(fields).serializeHash(),
            target: $(_btn).parent(),
            onReady: function(result, text) {
                $(_btn).parent().html(text || '<div class="tc-saved"><p>Сравнение сохранено в «<a href="/my-tours">Мои туры</a>»</p><strong>'+ this.data.title +'</strong>'+ this.data.comment +'</div>');
            }
        }); 
    },
    
    selectRow: function(elem)
    {
        $(elem).parents('tr:first').toggleClass('selected-row');
        if ($('input.select-table-row:checked', $(elem).parents('table:first')).length) {
            $('.grid-toolbar').addClass('grid-toolbar-active');
        } else {
            $('.grid-toolbar').removeClass('grid-toolbar-active');
        }
    }
}

SiteUser = {
    
    login: function()
    {
        var fields = $('#user-auth-form input');
        if (!fields.validate(false)) {
            return false;
        }
        $.jsHttpRequest({
            url: '/site/index/login',
            data: fields.serializeHash(),
            onReady: function(result, text) {
                if (typeof(result.error) != 'undefined') {
                    alert(result.error);
                    return;
                }
                
                $('#body').addClass('user-auth').addClass('user-auth-' + result.client.agent);
                
                switch (result.client.agent) {
                    case 'agency':
                        $('#user-name').text(result.client.agency.name);
                        break;
                    case 'manager':
                        $('#user-name').text(result.client.manager.name);
                        break;
                    case 'network':
                        $('#user-name').text(result.client.network.name);
                        break;
                }
            },
            cache: false,
            target: '#user-auth-form'
        });
    },
    
    logout: function() 
    {
        $.jsHttpRequest({
            url: '/site/index/logout',
            onReady: function(result, text) {
                $('#body').removeClass('user-auth user-auth-agency user-auth-manager user-auth-network');
            },
            cache: false,
            target: '#user-auth-form'
        });
    },
    
    myTour: 
    {
        add: function(elem)
        {
            $.jsHttpRequest({
                url: '/tour/add-to-my-tours',
                data: { 'tourId': $(elem).attr('tour') },
                target: elem,
                onReady: function(result, text) {
                    if (!text) {
                        $(elem).hide().next().show();
                        $('.my-tours-count').text(parseInt($('.my-tours-count:first').text()) + 1);
                    }                   
                },
                cache: false
            });        
        },
        
        remove: function(elem)
        {
            $.jsHttpRequest({
                url: '/tour/remove-from-my-tours',
                data: { 'tourId': $(elem).attr('tour') },
                target: $(elem).parent(),
                onReady: function(result, text) {
                    if (!text) {
                        if (!$(elem).parent().hasClass('already-in-may-tour')) {
                            $(elem).parents('tr:first').hide();
                        } else {
                           $(elem).parent().hide().prev().show();
                           $('.my-tours-count').text(parseInt($('.my-tours-count:first').text()) - 1);
                        }
                    }                   
                },
                cache: false
            });         
        }
    },
    
    agency: {
        
        _dialog: null,
        
        saveDogovor: function(button)
        {
            if (SiteUser.agency._dialog) {
                return SiteUser.agency._dialog.dialog('open');
            }
            SiteUser.agency._dialog = $('#agency-dogovor-form').dialog({
                title: 'Информация о агентстве',
                height: 530,
                width: 500,
                buttons: {
                    'Скачать договор' : function() {
                        if (!$(':input', this).validate()) {
                            return false;
                        }
                        location.href = button.href + '?' + $(SiteUser.agency._dialog).serialize();
                    },
                    'Отменить': function() {
                        $(this).dialog('close');
                    }
                }
            });
        }
        
    }
}

UserDiscount = {
    _dialog: null,
    
    show: function()
    {
        if (UserDiscount._dialog !== null) {
            UserDiscount._dialog.dialog('open');
            return;
        }
        UserDiscount._dialog = $('#user-discount').dialog({
            title: 'Узнайте размер своей скидки',
            height: 230,
            width: 500,
            buttons: {
                'Узнать скидку' : function() {
                    if (!$(':input', this).validate()) {
                        return false;
                    }
                    $.jsHttpRequest({
                        url: '/site/info/user-discount/',
                        data: $(this).serializeHash(),
                        onReady: function(result, text) {
                            $('#user-discount div.f-form').hide();
                            $('#user-discount div.report-zone').html(text ? 'Ваша скидка составляет ' + text : 'Турист с такими данными не найден').show('slow');
                            UserDiscount._dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        },
                        target: this
                    });                                
                },
                'Отменить' : function() {
                    $('#user-discount div.f-form').show();
                    $('#user-discount div.report-zone').hide();
                    $(this).dialog('close');
                }
            },
            close: function(ev, ui) { 
                  $('#user-discount div.f-form').show();
                  $('#user-discount div.report-zone').hide();
             } 
        });
    }    
}

WorkShop = {
    _dialog: null,
    _dialogTypes: { workshop: 'семинаре', tour: 'рекламном туре' },
    
    show: function(workshopId, name, date, type)
    {
        $('#work-shop-form span.workshopName').html('<b class="f-text">' + name + '</b>');
        $('#work-shop-form span.workshopDate').html('<b class="f-text">' + date + '</b>');
        $('#work-shop-form input[name=workshopId]').val(workshopId);
        
        WorkShop._dialog = $('#work-shop-form').clone().dialog({
            title: 'Заявка на участие в ' + (WorkShop._dialogTypes[type] || 'мероприятии'),
            height: 400,
            width: 510,
            buttons: {
                'Отправить' : function() {
                    if (!$(':input', this).validate()) {
                        return false;
                    }
                    $.jsHttpRequest({
                        url: '/site/info/workshop-request/',
                        data: $(this).serializeHash(),
                        onReady: function(result, text) {
                            $('#work-shop-form div.f-form').hide();
                            $('#work-shop-form div.report-zone').html(text || 'Ваша заявка успешно добавлена. Наш менеджер свяжется с вами в ближайшее время').show('fast');
                            WorkShop._dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        },
                        target: this
                    });                                
                },
                'Отменить': function() {
                    WorkShop._clear();
                    WorkShop._dialog.dialog('close');
                }
            },
            close: function(ev, ui) { WorkShop._clear(); } 
        });
    },
    
    _clear: function()
    {
	     $('#work-shop-form div.f-form').show();
	     $('#work-shop-form div.report-zone').hide();
	     $('#work-shop-form input').val('');
    }    
}

TourReward = {
    _dialog:     null,
    _dialogList: null,
    
    over: function(elem)
    {
        $('> *', $(elem).parent().addClass('reward-star-box-hover')).removeClass('reward-star-hover');
        $(elem).add($(elem).prevAll()).addClass('reward-star-hover');
    },
    
    out: function(elem)
    {
        $(elem).parent().removeClass('reward-star-box-hover');
    },
    
    set: function(elem)
    {
        if (elem && $(elem).hasClass('reward-star')) {
            $(elem).siblings().removeClass('reward-star-active');
            $(elem).add($(elem).prevAll()).addClass('reward-star-active');
            if (!$(elem).parents('#add-tour-reward').size()) {
                $('#add-tour-reward .reward-star')
                    .removeClass('reward-star-active')
                    .slice(0, $(elem).parent().find('.reward-star-active').size())
                    .addClass('reward-star-active');
            }
        }
        if (TourReward._dialog !== null) {
            TourReward._dialog.dialog('open');
            return;
        }
        TourReward._dialog = $('#add-tour-reward').dialog({
            title: 'Оцените программу тура',
            height: 300,
            width: 500,
            buttons: {
                'Сохранить': function() {
                    if (!$(':input', this).validate()) {
                        return false;
                    }
                    var params       = $(this).serializeHash();
                    params['reward'] = $('.reward-star-active', this).size();
                    var rewardBox    = this;
                    $.jsHttpRequest({
                        url: '/tour/add-reward',
                        data: params,
                        onReady: function(result, text) {
                            if (text) {
                                $('#add-tour-reward').html(text);
                                return;
                            }
                            
                            $('#add-tour-reward').html('<div style="margin: 10px;" class="result-ok">Отзыв успешно сохранен</div>');
                            $('.add-reward-button', rewardBox).replaceWith('<div class="reward-has-voted">Ваш отзыв принят</div>');
                            TourReward._dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(rewardBox).dialog('close'); } });
                        },
                        target: rewardBox
                    });
                },
                'Отменить': function() { $(this).dialog('close'); }
            } 
        });
    },
    
    showList: function()
    {
        if (TourReward._dialogList !== null) {
            TourReward._dialogList.dialog('open');
            return;
        }
        TourReward._dialogList = $('#tour-reward-list').dialog({
            title: 'Список отзывов и оценок',
            height: 400,
            width: 600,
            buttons: { 
                'Добавить отзыв': function() { $(this).dialog('close'); TourReward.set(); },
                'Закрыть': function() { $(this).dialog('close'); }
            }
        });
    }
}

Subscribe = {
    
    spo: function()
    {
        $('#spo-subscribe-dialog').remove();
        
        var _dialog = $('<div id="spo-subscribe-dialog"></div>').dialog({
            title: 'Подписка на новые спецпредложения, акции, раннее бронирование',
            height: 310,
            width: 550,
            buttons: {
                'Закрыть': function() { $(this).dialog('destroy'); }
            } 
        });
        
        $.jsHttpRequest({
            url: '/spo/subscribe-form',
            cache: false,
            onReady: function(result, text) {
                _dialog.html(text);
                Tools.prepareInputDefaultValue(_dialog);
            }
        });
    },
    
    saveSpo: function(button)
    {
        var box   = $(button).parent();
        var email = $('input.emailval', box);
        var phone = $('input.phoneval', box);
        if (!email.validate() || !phone.validate()) return false;
        
        $.jsHttpRequest({
            url: '/spo/add-subscribe',
            data: { 'email': email.hasClass('input-default-value') ? '' : email.val(), 'phone': phone.hasClass('input-default-value') ? '' : phone.val() },
            onReady: function(result, text) {
                box.find('.subscribe-result').show().siblings().remove();
            },
            target: box
        });
    }
}

Anketa = {
    save: function(form)
    {
		if (!$(':input', form).validate()) {
	       return false;
	    } 
        $.jsHttpRequest({
            url: '/site/info/save-anketa/',
            data: $(form).serializeHash(),
            onReady: function(result, text) {
                $(form).html('<div style="border-top: 1px dashed grey; padding-top: 20px; margin-top: 20px; text-align: center;">' + (text || 'Благодарим Вас за заполнение анкеты! <br />Информация обрабатывается и в ближайшее время мы свяжемся с Вами для урегулирования вопроса по получению Клубной карты компании. <br />Если у Вас возникнут вопросы, Вы можете обратиться к нам написав по почте <a href="mailto: it@dsbw.ru">it@dsbw.ru</a>.') + '</div>');
            }
        });
    },
    
    addToBlackList: function(form)
    {
		if (!$(':input', form).validate()) {
	       return false;
	    } 
        $.jsHttpRequest({
            url: '/site/info/save-unsubscribe-phone/',
            data: $(form).serializeHash(),
            onReady: function(result, text) {
                console.log(text);
                $(form).html('<div style="border-top: 1px dashed grey; padding-top: 20px; margin-top: 20px; text-align: center;">Вы отписаны от рассылки компании DSBW</div>');
            }
        });
    }
}

Tools = 
{
    // таймаут отображения статуса
    _statusTime: [],
    
    // уникальный id статуса. для разруливания моментов, когда статус изменился при автоматическом скрытии
    _statusUid: null,
    
    _request: {},

    LOADER: '',
    
    getRequest: function(name)
    {
        if (!name) return Tools._request;
        return typeof(Tools._request[name] !== 'undefined') ? Tools._request[name] : null;
    },
    
    showStatus: function(message, timeout, options)
    {
    },

    hideStatus: function(uid, options)
    {
    },
    
	prepareDatePicker: function(container) {
		$('input.ui-datepicker-field', container).each(function() {
			if (!this.id) this.id = ('dp' + Math.random()).replace('.', '');
			$(this).datepicker({
				onSelect: function(date) {
					if ($(this).attr('callback')) {
						var callback = eval($(this).attr('callback'));
						if (typeof callback == 'function')
							callback(date, this);
					}
				},
				dateFormat: 'dd.mm.yy',
                changeMonth: true,
                changeYear: true,
                yearRange: '-90:+05'
			});
		});
	},
	
	prepareInputDefaultValue: function(container)
    {
        $('.input-default-value', container).bind('focus click', function() {
            if (!$(this).attr('default') || $(this).attr('default') == $(this).val()) {
                $(this).attr('default', $(this).val()).val('').removeClass('input-default-value');
            }
        }).blur(function() {
            if ($(this).val() === '') {
                $(this).addClass('input-default-value').val($(this).attr('default'));
            }
        });
    },
    
	prepareTooltip: function(container)
    {
        $('.tooltip-box', container).tooltip({
            track: true,
            delay: 100,
            showURL: false,
            showBody: ' :: '
        });
    },
    
    lightBox: function(container)
    {
        $(container).lightBox({
            imageLoading:   '/public/library/plugin/lightbox/images/lightbox-ico-loading.gif',
            imageBtnPrev:   '/public/library/plugin/lightbox/images/lightbox-btn-prev.gif',
            imageBtnNext:   '/public/library/plugin/lightbox/images/lightbox-btn-next.gif',
            imageBlank:     '/public/library/plugin/lightbox/images/lightbox-blank.gif',
            imageBtnClose:  '/public/site/images/icons/close-btn.gif',
            overlayOpacity: 0.6
        });
    },
	
	popup: function(url, settings)
	{
	    var defaults = { width: 800, height: 600, scrollbars: 1, resizable: 1 };
	    if (typeof(settings) === 'string') {
	        $.each(settings.split(/\s*\,\s*/), function(i, el) {
	            var match = el.split(/\s*\=\s*/);
	            defaults[match[0]] = match[1];
	        });
	    }
	    var out = [];
	    for (name in defaults) {
	        out.push(name +'='+ defaults[name]);
	    }
	    return window.open(url, '', out.join(', '));
	},
	
	updateUrlParams: function(url, params)
    {
        var _params = clone(params);
        
        url = url.split('?');
        if (url.length > 1) { 
            $.each(url.pop().split('&'), function(i, elm) {
                elm = elm.split('=');
                if (elm.length > 1 && typeof(_params[elm[0]]) == 'undefined') {
                    _params[elm[0]] = elm[1];
                }
            });
        }
        var result = [];
        $.each(_params, function(i, elm) {
            result.push(i+'='+elm);
        });
        
        return url[0] +'?'+ result.join('&');
    },
    
    updatePrintVerLink: function(params)
    {
        $('a.print-version-link').each(function() {
            this.href = Tools.updateUrlParams(this.href, params);
        });
    },
    
    switchTab: function(elem)
    {
        if (!$(elem).hasClass('active')) {
            var parent = $(elem).parent();
            var index = $(' > a', parent).removeClass('active').index(elem);
            $(elem).addClass('active');
            parent.nextAll().hide().eq(index).show();
        }
    },
    
    mcBanner: 
    {
        _mcBannerTimeoutCallback: null,
        
        click: function(elem)
        {
            if ($(elem).hasClass('active')) return;
            var width = $(elem).css('width');
            $(elem)
                .addClass('active')
                .css('width', 'auto')
                .siblings('.active')
                .css('width', 'auto')
                .animate({'width': width}, 'slow')
                .removeClass('active');
        },
        
        over: function(elem)
        {
            Tools.mcBanner._mcBannerTimeoutCallback = setTimeout(function() { $(elem).trigger('click'); }, 500);
        },
        
        out: function()
        {
            clearTimeout(Tools.mcBanner._mcBannerTimeoutCallback);
        }
    },
    
    go2cat: function(button)
    {
        window.location = $(button).parent().prev().find('a:last').trigger('click').attr('href');
    },
    
    onlineLink: 
    {
        _menuTimeout: null,
        
        over: function(elem)
        {
            Tools.onlineLink._menuTimeout = setTimeout(function() {
                if (!$(elem).attr('width')) $(elem).attr('width', $(elem)[0].scrollWidth );
                $(elem).siblings().animate({'width' : 35 }, 'fast');
                $(elem).animate({'width' : 8 + parseInt($(elem).attr('width')) }, 'fast');
            }, 100);
        },
        
        out: function()
        {
            clearTimeout(Tools.onlineLink._menuTimeout);
        }
    },
    
    showAllItems: function(elem, text, items)
    {
        text = text || 'скрыть';
        if (items) {
            $(items).toggle();
        } else {
            $(elem).parent().siblings('.hidden-item').slideToggle();
        }
        if (!$(elem).attr('lastText')) $(elem).attr('lastText', $('u', elem).text());
        $(elem).html($('u', elem).text() == text ? '<u>'+$(elem).attr('lastText')+'</u>&nbsp;&darr;' : ('<u>'+ text +'</u>&nbsp;&uarr;'));
    },
    
    showFullTourRecommend: function(elem)
    {
        $('.tinfo-recommend-preview, .tinfo-recommend-description', $(elem).parents('.tinfo-recommend-box:first')).toggle();
    },
    
    accordion: function(elem) 
    {
        var elem = $(elem);
        if (elem.hasClass('sb-title-active')) return;
        elem.siblings('.sb-title-active').removeClass('sb-title-active');
        elem.addClass('sb-title-active').next('.sb-content').slideDown().siblings('.sb-content:visible').slideUp('normal', function() {
            if (elem.nextAll('.sb-title').length) {
                elem.siblings('b.r3, b.r4').removeClass('r-bottom');
            } else {
                elem.siblings('b.r3, b.r4').addClass('r-bottom');
            }
        });
    },
    
    
    showSendByEmailForm: function(url)
    {
        var _dialog = $('#send-by-email-form').clone().attr('id', '').dialog({
            title: 'Отправить ссылку на текущую страницу по эл. почте',
            height: 220,
            width: 400,
            buttons: {
                'Отправить': function() {
                    if (!$(':input', this).validate()) {
                        return false;
                    }
                    var params    = $(this).serializeHash();
                    params['url'] = url || ('' + window.location);
                    
                    _dialog.css('background', 'url("/public/projectz/images/ajax-loader.gif") no-repeat center').html('');
                    _dialog.dialog('option', 'buttons', {});
                    $.jsHttpRequest({
                        url: '/site/index/send-page-by-email',
                        data: params,
                        onReady: function(result, text) {
                            _dialog.css('background', '').html('<div style="margin: 10px;" class="result-ok">Ссылка отправлена на указанный адрес</div>');
                            _dialog.dialog('option', 'buttons', { 'Закрыть': function() { $(this).dialog('close'); } });
                        }
                    });
                },
                'Отменить': function() { $(this).dialog('close'); }
            } 
        });
    },
    
    list: 
    {
        showItem: function(element, id)
        {
            $(element).parents('.info-content-box:first')
                .find('.show-all').show()
                .end().find('.group-item').hide()
                .filter('.group-item-' + id).slideDown();
        },
        
        _text: null,
        
        search: function(input)
        {
            this._text = input.value;
            var items  = $('div.group-item', $(input).parents('div.info-content-box:first'));
            if (this._text) {
                items.each(this._containsFilter);
            } else {
                items.show().removeClass('active');
            }
        },
        
        _containsFilter: function(i, el)
        {
            if ($(el).text().toUpperCase().indexOf(Tools.list._text.toUpperCase()) >= 0) {
                $(el).show().addClass('active');
            } else {
                $(el).hide().removeClass('active');
            }
        } 
    },
    
    syncWidth: function(element, container)
    {
        var tblWidth = $(element).width();
        if ($(container || '#body').width() < tblWidth) {
            $(container || '#body').css('width', (tblWidth + 50) + 'px');
        }
    },
    
    _linkTracker: function(href)
    {
        if (typeof(pageTracker) !== 'undefined') {
            pageTracker._link(href);
        }
    }
}

Search = 
{
    find: function(form, url, button)
    {
        form = form || '#searchForm';
        
        if (!$(':input', form).validate()) {
            return false;
        }
        
        $(button).val('Найти...').attr('disabled', true);
        location.href = (url || '/search') +'?'+ $('[value!=""]', form).serialize() + '&autoStartSearch=tour';
    },
    
    toggleFlag: function(button, value, value2, isParent)
    {
        $(button).addClass('active').siblings('a').removeClass('active');
        var parent = isParent ? $(button).parent().parent() : $(button).parent();
        parent.find('input:first').val(value);
        if (typeof(value2) != 'undefined') {
            parent.find('input').eq(1).val(value2);
        }
    },

    changeCatalog: function(catalogSelect)
    {
        $('#psf-tour-form-partition-select').css('opacity', 0.6);
        
        $.ajax({ 
            url: '/site/price-xml/tour-partitions-select', 
            data: { 'catalog': $(catalogSelect).val(), 'callback': 'Search._loadCatalogPartsCallback' }, 
            dataType: 'script', 
            scriptCharset: 'utf-8'
        });
    },

    _loadCatalogPartsCallback: function(dict)
    {
        var _options = ['<option value=""> -- все разделы -- </option>'];
        $.each(dict, function(id, name) {
            _options.push('<option value="'+ id +'">'+ name +'</option>');
        });
        
        $('#psf-tour-form-partition-select')
            .html(_options.join(''))
            .css('opacity', 1);
    }
}


PriceTable = 
{
    calcAdditionalServices: function(input, autoSelect)
    {
        var table = $(input).parents('table.price-list-table:first');
        
        table.find('td.add-serv-cost').html('&nbsp;');
        
        if (autoSelect) {
            $(input).parents('tr:first').find('input:checkbox').attr('checked', $(input).val() > 0 ? true : false);
        }
        
        var additionalCost = 0;
        
        table.find('.additional-services:has(input:checked)').each(function(i, elm) {
            var count = $('select.add-serv-count', elm).val();
            
            if (count == 0) {
                $('select.add-serv-count', elm).val(1);
                count = 1;
            }
            
            var price = $('td.add-serv-price', elm).text(); 
            
            var cost = parseFloat(price) * parseInt(count);
            additionalCost += cost;
            $('td.add-serv-cost', elm).html(cost);
        });
        
        var totalPrice = $('.total-cost', table);
        
        if (!totalPrice.attr('cost')) {
            totalPrice.attr('cost', totalPrice.text());
        }
        
        totalPrice.text(parseFloat(totalPrice.attr('cost')) + parseFloat(additionalCost));
    },
    
    preparePriceListPrintUrl: function(link)
    {
        var service = [];
        $(link).parents('.price-list-box:first').find('.additional-services:has(input:checked)').each(function(i, elm) {
            var select = $('select.add-serv-count', elm);
            service.push('service['+ select.attr('servId') +']='+ select.val());
        });
        return service ? '&' + service.join('&') : '';
    },
    
    togglePriceList: function(button)
    {
        var parent = $(button).parents('tr:first');
        var tr     = parent.nextAll('tr.price-list-box:first').hide();
        var boxes  = tr.find('.price-list-box').hide();
        
        if ($(button).hasClass('active-price-list')) {
            $(button).removeClass('active-price-list');
            return;
        }
        
        parent.find('.active-price-list').removeClass('active-price-list');
        $(button).addClass('active-price-list');
        tr.show();
        boxes.filter('.code2-' + $(button).attr('code2')).slideDown();
    },
    
    changeCurrency: function(elem)
    {
        if ($(elem).hasClass('active')) return;
        var form = $(elem).parents('form:first');
        $('input[name=currency]', form).val($(elem).attr('currency'));
        PriceTable.update(form);
        $(elem).addClass('active').siblings().removeClass('active');
    },
    
    update: function(form, disableCache)
    {
        var data = $(form).serializeHash();
        var _error = $('div.error-message', form).hide();
        $.jsHttpRequest({
            url: $(form).attr('action'),
            data: data,
            cache: !disableCache, 
            target: $('.price-table-box', form),
            onReady: function(result, text) {
                if (result.error) {
                    _error.show().html('<h3>' + result.error + '</h3>Выберите другую дату, отель или вариант тура');
                    return;
                }
                Tools.updatePrintVerLink(data);
                $('.price-table-box', form).html(text);
                Tools.prepareTooltip(form);
            }
        }); 
    },
    
    showOnlineHotel: function(url)
    {
        Tools.popup(url, 'width=780, height=650, scrollbars=1');
        return false;
    },
    
    showMtHotel: function(url)
    {
        Tools.popup(url, 'width=780, height=650, scrollbars=1');
        return false;
    },

    showCityDescription: function(cityId)
    {
        Tools.popup('/city/' + cityId + '?popup=1', 'width=665, height=650');
        return false;
    },

    showOrderStatus: function(input)
    {
        if ($(input).val() && $(input).val() != 'Статус брони') {
            Tools.popup('http://online.dsbw.ru/status.php?a=dsbw&OrderNum=' + $(input).val(), 'width=600, height=500');
        } else {
            alert('Введите номер брони!');
        }
    },
    
    saveFinderToXls: function(form, button)
    {
        $(button).addClass('a-icon-loading');
        location.href = '/tour/price-finder-export?' + $(form).serialize();
        setTimeout(function() { $(button).removeClass('a-icon-loading'); }, 10000); 
    },
    
    spo: {
        
        showInfo: function(button)
        {
            $('#pricetable-spo-info').remove();
            
            var _dialog = $('<div id="pricetable-spo-info"></div>').dialog({
                title: 'Спецпредложение — скидка на выбранную цену',
                height: 480,
                width: 600
            });
            
            _dialog.css('background', 'url("/public/projectz/images/ajax-loader.gif") no-repeat center').html('');
            $.jsHttpRequest({
                url: $(button).attr('href'),
                data: { catalog: Tools.getRequest('catalog'), partition: Tools.getRequest('partition') },
                target: _dialog,
                cache: false,
                onReady: function(result, text) {
                    
                    _dialog.css('background', 'none').html(text);
                    
                    var _urlLink = $('#pricetable-spo-info-url');
                    _urlLink.attr('href', window.location.protocol +'//'+ window.location.hostname + window.location.pathname + _urlLink.attr('href'));
                    
                    Tools.prepareDatePicker(_dialog);
                    Tools.prepareTooltip(_dialog);
                    
                    _dialog.dialog('option', 'buttons', { 
                        'Сохранить': function() {
                            $.jsHttpRequest({
                                url: '/spo/price-spo-save',
                                target: _dialog,
                                data: { q: $('form:first', _dialog).get(0) },
                                cache: false,
                                onReady: function(result, text) {
                                    if (text) return alert(text);
                                    _dialog.dialog('destroy');
                                    PriceTable.update($(button).parents('form:first'), true);
                                }
                            });
                        }, 
                        'Удалить': function() {
                            if (!confirm('Удалить спецпредложение?')) return;
                            
                            $.jsHttpRequest({
                                url: '/spo/price-spo-remove',
                                target: _dialog,
                                data: $('form:first', _dialog).serializeHash(),
                                cache: false,
                                onReady: function(result, text) {
                                    if (text) return alert(text);
                                    _dialog.dialog('destroy');
                                    PriceTable.update($(button).parents('form:first'), true);
                                }
                            });
                        } 
                    });
                    
                    _dialog.css('overflow', 'visible');
                }
            });
        },
        
        changeHotel: function(select)
        {
            $('option', '#price-spo-subCode1, #price-spo-subCode2').each(function() {
                if (!$(this).attr('codeId')) return $(this).attr('selected', true);
                $(this).attr('codeId') == select.value ? $(this).show() : $(this).hide();
            });
        },
        
        toggleActualStatus: function(button, spoId)
        {
            var _isActual = $(button).attr('src').match('-empty.png');
            $(button).attr('src', $(button).attr('src').replace((_isActual ? '-empty' : '') + '.png', (!_isActual ? '-empty' : '') + '.png'));
            
            $.jsHttpRequest({
                url: '/spo/price-spo-toggle-actual',
                data: { 'spoId': spoId, 'isActual': _isActual ? 1 : 0 },
                target: $(button).parent().parent(),
                cache: false
            });
        }
    }
}

TourInfo = 
{
    switchTab: function(button, extraParams)
    {
        if ($(button).hasClass('active') && !extraParams) return;

        var _parent = $(button).parent();
        var _index = $(' > a', _parent).removeClass('active').index(button);
        $(button).addClass('active');
        var _newTab = _parent.nextAll().hide().eq(_index).show();
        
        if (!_newTab.is(':empty') && !extraParams) return;
        
        var _section = button.href.split('/').reverse()[0];
        
        $.jsHttpRequest({
            url: '/tour/info/',
            data: $.extend({ 'tourId': _parent.attr('tourId'), 'section': _section }, extraParams || {}),
            target: _parent,
            onReady: function(result, text) {
                _newTab.html(text);
                Tools.prepareTooltip(_newTab);
                
                if (_section == 'excursions') {
                    $('a.info-menu-item', _newTab).click(function() {
                        TourInfo.switchTab(button, { 'excursionId': $(this).attr('href').split('=').reverse()[0] })
                        return false;
                    });
                }
            }
        });
    }
}

RateCalc =
{
    euroRate: 0,

    calculate: function()
    {
        $('#calcInput').val($('#calcInput').val().replace(/[^\d\.]/ig, ''));

        var fromCurrency = RateCalc._getFromCurrency();
		
        if (fromCurrency == 'RUB') {
            $('#calcCurrencyRub').hide();
            $('#calcResultRub').hide();
            $('#calcCurrencyEur').show();
            $('#calcResultEur').show();
        } else {
            $('#calcCurrencyRub').show();
            $('#calcResultRub').show();
            $('#calcCurrencyEur').hide();
            $('#calcResultEur').hide();
        }
        
        valueRub = Math.round($('#calcInput').val() * RateCalc._getRate(fromCurrency, 'RUB')*100)/100;
        valueUsd = Math.round($('#calcInput').val() * RateCalc._getRate(fromCurrency, 'USD')*100)/100;
        valueEur = Math.round($('#calcInput').val() * RateCalc._getRate(fromCurrency, 'EUR')*100)/100;
        
        $('#calcResultRub').html(this._createNiceNumber(valueRub + ''));
        $('#calcResultUsd').html(this._createNiceNumber(valueUsd + ''));
        $('#calcResultEur').html(this._createNiceNumber(valueEur + ''));
    },

    _getRate: function(fromCurrency, toCurrency)
    {
        this.euroRate = parseFloat($('#euro-rate-value').val().replace(',', '.'));
        return fromCurrency == 'EUR' ? this.euroRate : (1 / this.euroRate);
    },

    _getFromCurrency: function()
    {
        $('#calcCurrencyList a').each(function() {
            if ($(this).hasClass('selected')) {
                result = $(this).attr('title');
            }
        });
        return result;
    },

    toggleCurrency: function(button)
    {
        $('#calcCurrencyList a').removeClass('selected');
        $(button).addClass('selected');
        RateCalc.calculate();
    },
    
    _createNiceNumber: function(value)
    {
        var fractionPart    = value.split(".");
        var fraction        = fractionPart[1];
        var number          = parseInt(value);
        
        while (number.length % 3 != 0) {
            number = ' ' + number;
        }
        
        chunks = this._str_split(number, 3);
        number = chunks.join(' '); 
        
        if (fraction) {
            number  += ',' + fraction;
        }       
        return number;      
    },
    
    _str_split: function(formatString, arrayLength)
    {
        formatString += '';  
        
        if (arrayLength == undefined) {  
            arrayLength = 1;  
        }  
        if (arrayLength) {  
            var result = [];  
            while(formatString.length > arrayLength) {  
               result[result.length] = formatString.substring(0, arrayLength);  
               formatString = formatString.substring(arrayLength);  
            }  
            result[result.length] = formatString;  
            return result;  
        }  
        return false;  
    }  
}

YML = {
    tour: function(elem)
    {
        $('#yml-dialog').remove();
        
        var _dialog = $('<div id="yml-dialog"></div>').dialog({
            title: 'Управление YML',
            height: 310,
            width: 550,
            buttons: {
                'Сохранить': function() { 
			        $.jsHttpRequest({
			            url: '/site/yml/save',
			            data: $('#yml-dialog').serializeHash(),
			            cache: false,
			            onReady: function(result, text) {
			                $(elem).css('opacity', $('input[name=isShow]', $('#yml-dialog')).is(':checked') ? '1' : '0.3');
			                // _dialog.html(text);
			                $('#yml-dialog').remove();
			            }
			        })},
                'Закрыть': function() { $(this).dialog('destroy'); }
            } 
        });
        
        $.jsHttpRequest({
            url: '/site/yml/item-form',
            data: { 'id': $(elem).attr('tourId') },
            cache: false,
            onReady: function(result, text) {
                _dialog.html(text);
            }
        });
    }
}


GoogleMap =
{
	map:           null,
	baseIcon:      null,
	directions:    null,
	waypoints:     null,
	waypointNames: null,
    _isInit:       null,
	
    init: function(loadGoogle)
	{
		if (typeof(google) == 'undefined') return;
        
        if (typeof(google.maps) == 'undefined') {
			if (loadGoogle) {
				// Загрузчик Google еще не выполнялся
				google.load('maps', '2.x', {
					'callback': function(){
						GoogleMap.init(false);
					},
	                'language': (($.browser.msie && $.browser.version == '6.0')?'en':'ru')
				});
			}
			return;
		}
        
        if (google.maps.BrowserIsCompatible() && $('#gmaps-frame').size()) {
			this.baseIcon = new google.maps.Icon();
			this.baseIcon.shadow = '/public/site/images/icons/google/shadow50.png';
			this.baseIcon.iconSize = new google.maps.Size(20, 34);
			this.baseIcon.shadowSize = new google.maps.Size(37, 34);
			this.baseIcon.iconAnchor = new google.maps.Point(9, 34);
			this.baseIcon.infoWindowAnchor = new google.maps.Point(9, 2);
			this.baseIcon.infoShadowAnchor = new google.maps.Point(18, 25);
			
			this.map = new google.maps.Map2($('#gmaps-frame')[0]);
            this.map.setUIToDefault();
            this.map.disableScrollWheelZoom();
		}		
    },
    
    _markerList: {},

	_createMarker: function(point, label, htmlContent) 
	{
    	var icon = new google.maps.Icon(this.baseIcon);
    	icon.image = '/public/site/images/icons/google/marker' + label +'.png';
        
    	var marker   = new google.maps.Marker(point, icon);
    	marker.label = label;

        if (htmlContent) {
            google.maps.Event.addListener(marker, 'click', function() {
                marker.openInfoWindowHtml(htmlContent);
            });
        }
        
        GoogleMap._markerList[point] = marker;
    	
    	return marker;
	},
    
    showMarker: function(posX, posY, htmlContent, zoom)
    {
        GoogleMap.map.clearOverlays();
        var coord = GoogleMap._createPoint(posX, posY);
        GoogleMap.map.setCenter(coord, zoom || 13);
        GoogleMap.map.addOverlay(GoogleMap._createMarker(coord, 'H', htmlContent));
    },
    
    showMarkerWindow: function(posX, posY)
    {
        var point = GoogleMap._createPoint(posX, posY);
        
        if (GoogleMap._markerList[point]) {
            GoogleMap.map.setZoom(14);
            GEvent.trigger(GoogleMap._markerList[point], 'click');
        }
    },
    
    showHotelOnMap: function(x, y, button) 
    {
        GoogleMap.showMarkerWindow(x, y);
        $(button).addClass('active').siblings('a').removeClass('active');
    },

    // отображение карты с отелями-маркерами
    load: function(id)
    {
		if (!GoogleMap.map) {
			GoogleMap.init(true);
		}
		
        $.jsHttpRequest({
            url: '/site/map/',
            data: { 'id' : id },
            onReady: function(result, text) 
            {
            	GoogleMap.map.clearOverlays();
                GoogleMap.map.setCenter(GoogleMap._createPoint(result.positionX, result.positionY), parseInt(result.zoom));
                
				for (var i = 0; i < result.markers.length; i++) {
					if (!result.markers[i].name) continue;
                    var htmlContent = GoogleMap._createHotelHtmlDescription(result.markers[i]);
					GoogleMap.map.addOverlay(GoogleMap._createMarker(GoogleMap._createPoint(result.markers[i].x, result.markers[i].y), i+1, htmlContent));
				}
                
                var mapHotels = $('#map-hotels-' + id);
                if (mapHotels.size()) {
                    mapHotels.show().siblings('span').hide();
                    mapHotels.parent().show();
                }
            }
        }); 
    },
    
    _createPoint: function(x, y)
    {
        return new GLatLng(parseFloat(y), parseFloat(x));
    },
    
    _createHotelHtmlDescription: function(hotel)
    {
        var _hotelClick = 'onclick="PriceTable.showMtHotel("/hotel/'+ hotel.masterId +'"); return false;"';
        
        return '<img '+ _hotelClick +' src="http://old.dsbw.ru/data/hotels_photo/'+ hotel.hotelID +'_small.jpg" onerror="$(this).remove()" class="hotel-image" width="182px" height="115px">' 
             + '<br>Отель <a href="/hotel/'+ hotel.masterId +'" class="outside-blue" '+ _hotelClick +'>'+ hotel.name +' '+ hotel.category +'</a>' 
             + (hotel.address ? '<br/>' + hotel.address : '')
             + (hotel.phoneNumber ? '<br/>' + hotel.phoneNumber : '');
    },
    
    route: function(id)
    {
        var isInit = GoogleMap._isInit;
        
		if (!GoogleMap.map) {
			GoogleMap.init(true);
		}
        
        $.jsHttpRequest({
            url: '/site/map/route/',
            data: { id: id },
            onReady: function(result, text) {
                if (result.route) {
                    
                    // если в маршруте всего один пункт, и при этом есть карты отелей — показываем первую из них
                    if (isInit && result.route.length == 1) {
                        var firstHotelMap = $('#hotel-tech-desc .hotel-map-link:first');
                        if (firstHotelMap.size()) {
                            firstHotelMap.trigger('click');
                            return;
                        }
                    }
                    
	            	GoogleMap.map.clearOverlays();
	            	
                	GoogleMap.waypoints = [];
                	GoogleMap.waypointNames = [];
                	
					for (var i = 0; i < result.route.length; i++) {
						GoogleMap.waypoints.push(new google.maps.LatLng(parseFloat(result.route[i].lat), parseFloat(result.route[i].lng)));
						GoogleMap.waypointNames.push(result.route[i].name);
					}

					GoogleMap.directions = new google.maps.Directions(GoogleMap.map);
                    GEvent.addListener(GoogleMap.directions, 'error', GoogleMap.onGDirectionsError);
	            	GoogleMap.directions.loadFromWaypoints(GoogleMap.waypoints);
                    
                    // если в маршруте всего одни пункт уменьшаем маштаб карты чтобы его было хорошо видно
                    if (result.route.length == 1) {
                        setTimeout(function() {
                            GoogleMap.map.setCenter(new GLatLng(parseFloat(result.route[0].lat), parseFloat(result.route[0].lng)), 6);
                        }, 500);
                    }
            	}
            }
        }); 
    },
    
    show: function(id)
    {
		GoogleMap._isInit = true;
        
        if (!GoogleMap.map) {
			GoogleMap.init(true);
		}
		
	    /* показываем маршрут тура по-умолчанию */
        if ($('#show-tour-route-link').size()) {
	        $('#show-tour-route-link').trigger('click');
        } else {
            $('#hotel-tech-desc .hotel-map-link:first').trigger('click');
        }
        
        GoogleMap._isInit = null;
	},
    
    onGDirectionsError: function(id)
    {
    	for (var i in GoogleMap.waypoints)
    	{
    		if (i == '0')
    		{
    			var ne = GoogleMap.waypoints[i];
    			var sw = GoogleMap.waypoints[i];
    		}
    		
    		if (GoogleMap.waypoints[i].lat() > ne.lat())
    		{
    			ne = new google.maps.LatLng(GoogleMap.waypoints[i].lat(), ne.lng());
    		}
    		
    		if (GoogleMap.waypoints[i].lng() > ne.lng())
    		{
    			ne = new google.maps.LatLng(ne.lat(), GoogleMap.waypoints[i].lng());
    		}
    		
    		if (GoogleMap.waypoints[i].lat() < sw.lat())
    		{
    			sw = new google.maps.LatLng(GoogleMap.waypoints[i].lat(), sw.lng());
    		}
    		
    		if (GoogleMap.waypoints[i].lng() < sw.lng())
    		{
    			sw = new google.maps.LatLng(sw.lat(), GoogleMap.waypoints[i].lng());
    		}
    		
    		GoogleMap.map.addOverlay(GoogleMap._createMarker(GoogleMap.waypoints[i], parseInt(i)+1, GoogleMap.waypointNames[i]));
    	}

    	var bounds = new google.maps.LatLngBounds(sw, ne);
    	
		GoogleMap.map.setCenter(bounds.getCenter(), GoogleMap.map.getBoundsZoomLevel(bounds));
		GoogleMap.directions = new google.maps.Polyline(GoogleMap.waypoints, '#0000ff', 3, 1, {geodesic:true});
		GoogleMap.map.addOverlay(GoogleMap.directions);
	}
}

ImageZoom = 
{
    box:    null,
    image:  null,
    offset: null,

    imageHeight: null,
    imageWidth:  null,
    boxHeight:   null,
    boxWidth:    null,

    init: function(container, image)
    {
        this.box         = $(container);
        this.image       = $(image);
        
        this._initDimensions();
        
        this.box.mousemove(this._move);
        this.box.hover(this._mouseover, this._mouseout);
        $(window).resize(this._initDimensions);
    },
    
    addMarker: function(htmlContent, posX, posY)
    {
        var marker = $('<div class="iz-marker" style="position: absolute;"></div>');
        marker.html(htmlContent);
        ImageZoom.image.show().append(marker);
        
        var _height = marker.height();
        var _width  = marker.width();
        
        marker.css({ top: posY - _height, left: posX - _width });
        
        var marker2 = marker.clone();
        ImageZoom.box.prepend(marker2);
        
        marker2.css({ 
            top: (posY * ImageZoom.boxHeight / ImageZoom.imageHeight) - _height, 
            left: (posX * ImageZoom.boxWidth / ImageZoom.imageWidth)  - _width
        });
        
        ImageZoom.image.hide();
        
        Tools.prepareTooltip(ImageZoom.box);
    },
    
    _initDimensions: function()
    {
        ImageZoom.offset      = ImageZoom.box.offset();
        ImageZoom.boxHeight   = ImageZoom.box[0].offsetHeight;
        ImageZoom.boxWidth    = ImageZoom.box[0].offsetWidth;
        
        ImageZoom.image.show();
        ImageZoom.imageHeight = ImageZoom.image[0].offsetHeight;
        ImageZoom.imageWidth  = ImageZoom.image[0].offsetWidth;
        ImageZoom.image.hide();
    },

    _move: function(event)
    {
        var m = ImageZoom.image[0];
        m.style.top  = ImageZoom._calcShift(event.pageY - ImageZoom.offset.top, ImageZoom.imageHeight, ImageZoom.boxHeight) + 'px';
        m.style.left = ImageZoom._calcShift(event.pageX - ImageZoom.offset.left, ImageZoom.imageWidth, ImageZoom.boxWidth) + 'px';
    },
    
    _mouseover: function()
    {
        ImageZoom.image.show();
    },
    
    _mouseout: function()
    {
        ImageZoom.image.hide();
    },
    
    _calcShift: function(pos, bigSize, smallSize)
    {
        var shift = (pos ? pos + 1 : 0) * (bigSize) / smallSize;
        return 0 - shift + pos;
    }
}

})();
