var zoomed = 'Zoomed'; // класс для увеличеного объекта
var currentFrame = 'Current'; // класс текущего фрейма
var hoverDelay = 200; // на сколько милисекунд задерживать мышку на объекте для последующего увеличения

/*
    Переход из первого состояния во второе или наоборот
    normalStateObj = z2.prev()
*/
$.fn.step1Zoom = function(normalStateObj, mode, callback, smallDesc) {
    
    var $this = $(this);
    var speed = 100;
    
    callback = callback || function(){};
    // узнаем параметры начального состояния объекта
    var normalParams = normalStateObj.getZoomInfo();
    // узнаем параметры конечного состояния объекта (каким будет объект после увеличения)
    var zoomedParams = this.getZoomInfo();


    if (mode == 'in') {

        $this.prev().invisible(); // прячем первое состояние
        
        if (smallDesc == undefined) {
            $this.find('div').show(); // показываем smallDesc
        }
        

    } else {

        var callbackCopy = callback;
        callback = function() { 
            callbackCopy(); 
            $this.prev().visible(); // показываем первое состояние
        }

        $this.find('div').hide(); // прячем smallDesc
    }

    this.zoom(mode, normalParams, zoomedParams, callback, speed);


}

/*
    Переход из второго состояния в третье или наоборот
*/
$.fn.step2Zoom = function(normalStateObj, mode, callback) {

    var $this = $(this);
    var frame = this.getFrame();
    
    callback = callback || function(){};
    // узнаем параметры начального состояния объекта
    var normalParams = normalStateObj.getZoomInfo();
    // узнаем параметры конечного состояния объекта (каким будет объект после увеличения)
    var zoomedParams = this.getZoomInfo();

    
    if (mode == 'in') {

        this.zoom(mode, normalParams, zoomedParams, function(){ // zoom in
            callback(); 
            $this.getFrame().wineDescription(mode); // показываем дескрипшн
        });
        zoomGallery.getCurrentFrame().frameStatus('notCurrent'); // деактивируем предыдущий фрейм
        this.frameStatus('current'); // активируемы текущий фрейм

    } else {

        $this.getFrame().wineDescription(mode, function(){ // прячем дескрипшн
            $this.zoom(mode, normalParams, zoomedParams, callback); // zoom out
        }); 
        
        this.frameStatus('notCurrent'); // деактивируем текущий фрейм
        var z2 = $this.prev();  z2.step1Zoom(z2.prev(), 'in', null, false); // показываем второе состояние зума
    }

    frame.producer(mode); // активируем/ДЕактивируем производителя
    
}


$.fn.allStepsZoom = function(normalStateObj, mode, callback){
    var $this = $(this);
    callback = callback || function(){};
    
    var z2 = $this.find('.z2');
    var z3 = $this.find('.z3');
    
    if (this.length) {
        z3.step2Zoom(z2, mode, function(){
            z2.step1Zoom(z2.prev(), mode, callback);
        });
        
    } else {
        callback();
    }
}



$.fn.wineDescription = function(mode, callback){
    var $this = $(this); // frame object
    callback = callback || function(){};

    var popUp = $('.PopUp[rel='+ $this.attr('id') +']');
    
    if (popUp.length) { // if description exists
        if (mode == 'in') {
            popUp.fadeIn();
        } else {
            popUp.fadeOut(callback);
        }
    } else {
        callback();
    }
}


$.fn.producer = function(mode){

    var q = '#' + $(this).attr('rel');
    var producer = $(q);
    
    if (mode == 'in') {
        producer.addClass('current');
    } else {
        producer.removeClass('current');
    }
}

/*
    если объект уже увиличен - то делается zoom out, если еще не увеличен - то zoom in
*/
$.fn.toggleZoom = function(){

    if (this.hasClass(zoomed)) {
        var mode = 'out';
    }
    this.zoom(mode);
}


$.fn.zoom = function(mode, normalParams, zoomedParams, callback, speed){
    
    var $this = $(this);
    callback = callback || function(){}; 

    switch (mode) {
        case 'out':     // zoom out
                        
                        $this.css(zoomedParams);
                
                        $this.animate(normalParams, speed,
                            function(){
                                $this.hide();
                                callback();
                                $this.attr('style', ''); // возвращаем элемент в его естественное состояние
                            }
                        );

                        $this.removeClass(zoomed);
            break;

        default:        // zoom in

                        $this.css(normalParams);

                        $this.show();
                        $this.animate(zoomedParams, speed, callback);

                        $this.addClass(zoomed);
            break;
    }
    
    return this;
    
}



/*
    Получаем параметры объекта, которые необходимы для зума
*/
$.fn.getZoomInfo = function(){
    var $this = $(this);
    var params = {};
    //this.is(':visible'); // возникают проблемы в Safari
    var isVisible = true;
    if (currentCss(this.get(0), 'display') === 'none') {
        isVisible = false;
    }
    toggleVisibility = !isVisible;

    if (toggleVisibility) {
        this.show();
    }
    
        params.width = this.width();
        params.height = this.height();
        params.top = currentCss($this.get(0), 'top');
        params.left = currentCss($this.get(0), 'left');
        
        $.each(params, function(k, v) {
            if (v == 'auto') {
                params[k] = 0;
            }
        });

    if (toggleVisibility) {
        this.hide();
    }
    
    return params;
}


/*
    Показывает объект используя свойство visible
*/
$.fn.visible = function(){
    return this.each(function(){
        var $this = $(this);
        $this.css('visibility', 'visible');
    });
}

/*
    Прячет объект используя свойство visible
*/
$.fn.invisible = function(){
    return this.each(function(){
        var $this = $(this);
        $this.css('visibility', 'hidden');
    });
}

/*
    Marks frame as active(current)
*/
$.fn.frameStatus = function(status){
    var $this = $(this);
    if ($this.hasClass('OneItem')){
        // if this is a frame
        var frame = $this;
    } else {
        // if it's a frame descedant
        var frame = $this.parents('.OneItem:first');
    }
    
    switch (status) {
        case 'current':    frame.addClass(currentFrame); break;
        default:           frame.removeClass(currentFrame); break;
    }
    
}

$.fn.getCurrentFrame = function(){
    return this.find('.'+currentFrame);
}


$.fn.getFrame = function(){
    return this.parents('.OneItem');
}

/*
    Возвращает скомпелированое css свойство
*/
function currentCss(el, cssprop){
    
    if (el.currentStyle) {
        //IE
        return el.currentStyle[cssprop];
        
    } else if (document.defaultView && document.defaultView.getComputedStyle) {
        //Firefox
        var actualStyles = window.getComputedStyle(el, '');
        if (actualStyles) {
            return actualStyles[cssprop];
        }
        
    } else {
        //try and get inline style
        return el.style[cssprop];
    }
    
    return null;

}


$.fn.onLongHover = function(callback, delay){
    
    var $this = $(this); // hovered object
    var timer = setTimeout(callback, delay);
    $this.bind('mouseout', function(){
        clearTimeout(timer);
    });
    
}




$(function(){

    //$('#Bottles').zoomGallery();
    zoomGallery = $('#Bottles');
    
    $('.OneItem a').bind('mouseover', function(e){
        var $this = $(this);
        $this.onLongHover(function(){ // запускаем зум только если мышка задерживается на объекте
            // делаем первый зум
            $this.next().step1Zoom($this, 'in');
        }, hoverDelay);
    });

    $('.OneItem .z2').bind('mouseout', function(e){
        var $this = $(this);
        $this.step1Zoom($this.prev(), 'out');

    }).click(function(e){
        var $this = $(this);
        zoomGallery.getCurrentFrame().allStepsZoom($this, 'out', function(){ 

            itemStrip.putFrameToPosition($this.getFrame(), 3, function(){
                $this.next().step2Zoom($this, 'in');
            });             

        });
        //$this.next().step2Zoom($this, 'in');
    })

    
    $('.OneItem .z3').click(function(){
        var $this = $(this);
        $this.step2Zoom($this.prev(), 'out');
    });
    
    // при клике на клоуз прячем дескрипшн
    $('.Descriptions .close').click(function(){
        var popUp = $(this).parents('.PopUp:first');
        var frame = $('#'+popUp.attr('rel'));
        frame.wineDescription('out');
    })
    
    $(zoomGallery).find('.arr').click(function(){
        var currentFrame = zoomGallery.getCurrentFrame();
        currentFrame.allStepsZoom(currentFrame.find('.z2'), 'out');
    })

    
})

$(window).bind('load', function(){
    var min = 0;
    var max = itemStrip.totalItems-1;
    var randomIndex = Math.floor(Math.random() * (max - min + 1)) + min;
    var randomIndex = 5;
    var normalState = $('.OneItem:eq('+ randomIndex +') a');
    var z2 = normalState.next();
    if (z2.length) {
        normalState.next().step1Zoom(normalState, 'in', function(){ z2.click() }, false);
    }
});

