myViewer = {
width : 950,
height : 700,
boxFadeInTime : 5,
boxFadeInStep : 20,
boxFadeOutTime : 5,
boxFadeOutStep : 20,

autolist : false,
autoNav : true,
time : 5000,

fadestart : 0,
fadestep : 10,
fadetime : 5,

navImgPrevious : 'previous.png',
navImgNext : 'next.png',
navImgClose : 'close.png',
navImgOpen : 'open.png',

idBox : 'myViewBox',
idView : 'myViewArea',
idControl : 'myViewControl',
idInfo : 'myViewInfo',
idNav : 'myViewNav',
idImages : 'myViewImages',
idBigImages : 'myViewBigImages',
enableBigImage : false,
prefixView : 'myViewImageId_',
box : null,
view : null,
control : null,
listImages : [],
listImagesObj : [],
curPos : 0,

imgLoader : 'ajax-loader.gif',
idLoader : 'myViewLoader',
idImageArea : null,        
idListImages : null,
animationTime : 250,
numFrames : 25,
timePerFrame : 10,
listImages : [],
listBigImages : [],
objImages : [],
handleImage : 0,

/** Таймеры. **/
timerAuto : null,
timerAnimation : null,
timerLoader : null,
/** Флаги. **/
flagAuto : false,
flagAnimation : false,
showLoaderFlag : false,
countEnter : 0

};

myViewer.screenSize = function() {
    var w, h;
    w = (window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth));
    h = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight));
    return {width:w, height:h};
}

myViewer.init = function(options) {
    if (options.navImgPrevious) this.navImgPrevious = options.navImgPrevious;
    if (options.navImgNext) this.navImgNext = options.navImgNext;
    if (options.navImgClose) this.navImgClose = options.navImgClose;
    if (options.navImgOpen) this.navImgOpen = options.navImgOpen;
    
    if (options.idImages) this.idImages = options.idImages;
    if (options.idBigImages) this.idBigImages = options.idBigImages;
    if (options.width != undefined) this.width = options.width;
    if (options.height != undefined) this.height = options.height;
    if (options.imgLoader != undefined) this.imgLoader = options.imgLoader;
    if (options.idLoader != undefined) this.idLoader = options.idLoader;
    this.autolist = (options.autolist !== undefined) ? options.autolist : this.autolist;
    this.autoNav = (options.autoNav !== undefined) ? options.autoNav : this.autoNav;
    if (options.previous != undefined) this.previous = options.previous;
    if (options.next != undefined) this.next = options.next;
    this.time = (options.time !== undefined) ? options.time : this.time;
    this.animationTime = (options.animationTime !== undefined) ? options.animationTime : this.animationTime;
    this.numFrames = (options.numFrames !== undefined) ? options.numFrames : this.numFrames;
    this.timePerFrame = this.animationTime / this.numFrames;
};

myViewer.open = function(options) {
    if (typeof options == 'object') this.init(options);
    var box = document.getElementById(this.idBox);
    if (!box) box = this.createBox();
    if (!box) return;
    // Установка интервала высплывания окна. 
    box.fadeInTimer = setInterval(function(obj) {
        return function() {
            obj.boxFadeIn();
        };
    }(this), this.boxFadeInTime);
};

myViewer.createBox = function(options) {
    if (typeof options == 'object') this.init(options);
    var obj = this;
    // Получение списка изображений.
    this.listImages = [];
    this.listImagesObj = [];
    var objListImages = document.getElementById(this.idImages);
    if (!objListImages) return;
    var listElemImages = objListImages.getElementsByTagName('a'); 
    if (listElemImages.length == 0) return;
    
    var objListBigImages = document.getElementById(this.idBigImages);
    if (objListBigImages) {
        var listElemBigImages = objListBigImages.getElementsByTagName('a');
    }
    
    // Координаты окна просмотра.
    var screenSize = this.screenSize();
    if ((this.width + 30) > screenSize.width) this.width = screenSize.width - 30;
    if ((this.height + 30) > screenSize.height) this.height = screenSize.height - 30;
    var left = Math.ceil((screenSize.width - this.width) / 2) - 10;
    var top = Math.ceil((screenSize.height - this.height) / 2);
    if (left < 0) left = 0;
    if (top < 0) top = 0;
    
    // Создание окна просмотра.
    var box = document.createElement('div');
    box.id = this.idBox;
    box.style.width = this.width + 'px';
    box.style.height = this.height + 'px';
    box.style.position = 'fixed';
    box.style.zIndex = 1000;
    box.style.top = top + 'px';
    box.style.left = left + 'px';
    box.style.opacity = 0;
    box.style.filter = 'alpha(opacity=0)';
    
    var controlHeight = 40;
    
    // Создание области просмотра.
    var view = document.createElement('div');
    view.id = this.idView;
    var heightView = this.height - controlHeight;
    view.style.position = 'relative';
    view.style.height = (heightView - 10) + 'px';
    view.style.margin = '2px';
        
    // Создание области управления.
    var control = document.createElement('div');
    control.id = this.idControl;
    control.style.height = controlHeight + 'px';
    control.style.position = 'static';
    control.style.margin = '2px';
    
    // Создание информационной области.
    var info = document.createElement('div');
    info.id = this.idInfo;
    info.style.height = 30 + 'px';
    //info.style.border = '1px solid #000';
    info.style.position = 'static';
    info.style.padding = '0px';
    info.style.paddingTop = '10px';
    info.style.paddingLeft = '10px';
    
    // Создание области навигации.
    var nav = document.createElement('div');
    nav.id = this.idNav;
    nav.style.height = 35 + 'px';
    //nav.style.border = '1px solid #000';
    nav.style.position = 'static';
    nav.style.margin = '2px';
    nav.style.width = '140px';
    nav.style.styleFloat = 'right';
    nav.style.cssFloat = 'right';
        
    // Создание структуры документа.
    box.appendChild(view);
    box.appendChild(control);
    control.appendChild(nav);
    control.appendChild(info);
    var docbody = document.getElementsByTagName('body');
    docbody[0].appendChild(box);
    
    // Получаем размеры области.
    var realWidth = view.offsetWidth;
    var realHeight = view.offsetHeight;
    
    this.realWidth = realWidth;
    this.realHeight = realHeight;
    //alert(realWidth);
    // Создание изображений.
    // Создание первого изображения.
    var firstImg = document.createElement('img');
    firstImg.style.visibility = 'hidden';
    firstImg.width = realWidth;
    firstImg.height = realHeight;
    firstImg.style.position = 'absolute';
    firstImg.style.margin = '0px';
    firstImg.style.border = '0px';
    firstImg.style.padding = '0px';
    //firstImg.style.zIndex = 2;
    firstImg.style.opacity = 0;
    firstImg.style.filter = 'alpha(opacity=0)';
    firstImg.style.cursor = 'pointer';
    firstImg.onclick = function() {
        obj.close();
    }; 
    
    // Создание второго изображения.
    var secondImg = document.createElement('img');
    secondImg.style.visibility = 'hidden';
    secondImg.width = realWidth;
    secondImg.height = realHeight;
    secondImg.style.position = 'absolute';
    secondImg.style.margin = '0px';
    secondImg.style.border = '0px';
    secondImg.style.padding = '0px';
    //secondImg.style.zIndex = 1;
    secondImg.style.opacity = 1;
    secondImg.style.filter = 'alpha(opacity=100)';
    view.appendChild(secondImg);
    view.appendChild(firstImg);
    
    // Создание области сообщения загрузки.
    var top = (realHeight / 2) - (42 / 2);
    var left = (realWidth / 2) - (116 / 2);
    var loaderContent = '<table><tr>';
    loaderContent += '<td><img src="' + this.imgLoader + '" /></td>';
    loaderContent += '<td><span class="loader_msg">Загрузка...</span></td>';
    loaderContent += '</tr></table>';
    var loader = document.createElement('div');
    loader.id = this.idLoader;
    loader.innerHTML = loaderContent;
    loader.style.position = 'absolute';
    loader.style.top = top + 'px';
    loader.style.left = left + 'px';
    //loader.style.zIndex = 3;
    loader.style.display = 'none';
    view.appendChild(loader);
    
    /** Сохранение объектов. **/
    this.handleImage = 0;
    this.objImages[this.handleImage] = firstImg;
    this.objImages[this.handleImage + 1] = secondImg;
    this.loader = loader;
    
    // Получение списка элементов.
    var j = 0;
    for (var i = 0; i < listElemImages.length; i++) {
        var srcImg = listElemImages[i].getAttribute('href');
        if (srcImg == undefined || srcImg == '') continue;
        if (srcImg.lastIndexOf) {
            var b = srcImg.lastIndexOf('.');
            if (b != -1) {
                var ext = srcImg.substring(b+1);
                ext = ext.toLowerCase();
                if (!((ext == 'jpg') || (ext == 'jpeg') || (ext == 'gif') || (ext == 'png'))) continue;
                
            }
        }
        this.listImages[j] = srcImg;
        ++j;
    }
    if (listElemBigImages) {
        var j = 0;
        for (var i = 0; i < listElemBigImages.length; i++) {
            var srcImg = listElemBigImages[i].getAttribute('href');
            if (srcImg == undefined || srcImg == '') continue;
            if (srcImg.lastIndexOf) {
                var b = srcImg.lastIndexOf('.');
                if (b != -1) {
                    var ext = srcImg.substring(b+1);
                    ext = ext.toLowerCase();
                    if (!((ext == 'jpg') || (ext == 'jpeg') || (ext == 'gif') || (ext == 'png'))) continue;
                }
            }
            this.listBigImages[j] = srcImg;
            ++j;
        }
    }
    /**
    this.handleImage = 0;
    var firstImg = this.objImages[this.handleImage];
    var secondImg = this.objImages[this.handleImage + 1];
    firstImg.style.opacity = 0;
    firstImg.style.filter = 'alpha(opacity=0)';
    //firstImg.src = this.listImages[0];
    secondImg.style.opacity = 1;
    secondImg.style.filter = 'alpha(opacity=100)';
    //secondImg.src = this.listImages[0];
    **/
    
    this.curPos = 0;
    this.slideImage(this.curPos);
    if (this.autolist && (this.listImages.length > 1)) this.auto();
    
    /**
    var loadImage = function(objImg) {
        var newSize = myViewer.resizeImage(objImg.width, objImg.height, realWidth - 20, realHeight - 20);
        objImg.width = newSize.width;
        objImg.height = newSize.height;
        var left = Math.ceil((realWidth - objImg.width) / 2) + 'px';
        var top = Math.ceil((realHeight - objImg.height) / 2) + 'px';
        objImg.style.left = left;
        objImg.style.top = top;
        objImg.style.visibility = 'visible';
    }
    
    // Построение списка изображений.
    var j = 0;
    var listImagesObj = [];
    for (var i = 0; i < listElemImages.length; i++) {
        var srcImg = listElemImages[i].getAttribute('href');
        if (srcImg == undefined || srcImg == '') continue;
        this.listImages[j] = srcImg;
        // Создание элементов изображений.
        var idImage = this.prefixView + j;
        listImagesObj[j] = document.createElement('img');
        listImagesObj[j].src = srcImg;
        view.appendChild(listImagesObj[j]);
        listImagesObj[j].style.position = 'absolute';
        listImagesObj[j].style.visibility = 'hidden';
        listImagesObj[j].id = idImage;
        listImagesObj[j].fade = this.fadestart;
        listImagesObj[j].style.opacity = listImagesObj[j].fade / 100;
        listImagesObj[j].style.filter = 'alpha(opacity=' + listImagesObj[j].fade + ')';
        
        if (window.addEventListener) {
            listImagesObj[j].addEventListener('load', function() {loadImage(this);}, false);
        } else {
            if (listImagesObj[j].onreadystatechange !== undefined) {
                listImagesObj[j].onreadystatechange = function() {
                    if (this.complete || (this.readyState == 'complete')) loadImage(this);
                }
                if (listImagesObj[j].complete || (listImagesObj[j].readyState == 'complete')) loadImage(listImagesObj[j]);
            } else {
                listImagesObj[j].onload = function() {loadImage(listImagesObj[j]);};
            }
        }
        ++j;
    }
    **/
    //this.curPos = 0;
    //if (this.listImages.length != 0) this.showImage(0);
    //if (this.autolist) this.auto();
    
    return box;
};

/** Показать загрузчик. **/
myViewer.showLoader = function() {
    this.showLoaderFlag = true;
    var loader = this.loader;
    loader.style.display = 'block';
    clearInterval(this.timerAuto);
    this.flagAuto = false;
};

/** Скрыть загрузчик. **/
myViewer.hideLoader = function() {
    this.showLoaderFlag = false;
    var loader = this.loader;
    loader.style.display = 'none';
    clearInterval(this.timerAuto);
    this.flagAuto = false;
    if (this.autolist) this.auto();
};

/** Автоматическое пролистывание. **/
myViewer.auto = function() {
    var obj = this;
    this.timerAuto = setInterval(function() {
        obj.list('1');
    }, this.time);
    this.flagAuto = true;
};

/**  Отобразить картинку. **/
myViewer.slideImage = function(key) {
    this.countEnter = 0;
    var srcImg = this.listImages[key];
    var bigImg = srcImg;
    if (this.listBigImages[key] != undefined) bigImg = this.listBigImages[key];
    var firstImg = this.objImages[this.handleImage];
    var secondImg = this.objImages[this.handleImage + 1];
    var obj = this;
    /** Отключение таймера загрузки. **/
    clearInterval(this.timerLoader);
    if (this.showLoaderFlag) this.hideLoader();
    
    
    firstImg.onload = function() {
        var tmpImg = new Image();
        tmpImg.src = srcImg;
        var newSize = obj.resizeImage(tmpImg.width, tmpImg.height, obj.realWidth - 20, obj.realHeight - 20);
        
        firstImg.width = newSize.width;
        firstImg.height = newSize.height;
        var left = Math.ceil((obj.realWidth - firstImg.width) / 2) + 'px';
        var top = Math.ceil((obj.realHeight - firstImg.height) / 2) + 'px';
        firstImg.style.left = left;
        firstImg.style.top = top;
        
        secondImg.width = newSize.width;
        secondImg.height = newSize.height;
        secondImg.style.left = left;
        secondImg.style.top = top;
        
        if (firstImg.style.visibility == 'hidden') firstImg.style.visibility = 'visible';
        
        obj.animateCSS(firstImg, obj.numFrames, obj.timePerFrame, {
            opacity : function(f, t, n) {return ((1 * f) / n )},
            filter : function(f, t, n) {
                var tmp = ((100 * f) / n);
                return 'alpha(opacity=' + tmp + ')';
            }}, 
            function(){
                secondImg.src = firstImg.src;
            }
        );
        secondImg.onload = function() {
            if (secondImg.style.visibility == 'hidden') secondImg.style.visibility = 'visible';
            firstImg.style.opacity = 0;
            firstImg.style.filter = 'alpha(opacity=0)';
        };
        if (obj.listImages.length > 1) {
            var info = document.getElementById(obj.idInfo);
            if (info) {
                var i = key;
                ++i;
                info.innerHTML = 'Изображение ' + i + ' из ' + obj.listImages.length;
            }
        }
        clearInterval(obj.timerLoader);
        if (obj.showLoaderFlag) obj.hideLoader();
    };
    
    // Кнопки навигации.
    var nav = document.getElementById(this.idNav);
    var navHref = '';
    navHref += '<a href="#" onclick="myViewer.close(); return false;"><img src="' + this.navImgClose + '" style="border: 0px; float: right;"></a>';
    navHref += '<a href="' + bigImg + '" target="_blank"><img src="' + this.navImgOpen + '" style="border: 0px; float: right;"></a>';
    if (this.listImages.length > 1) {
        navHref += '<a href="#" onclick="myViewer.nav(1); return false;"><img src="' + this.navImgNext + '" style="border: 0px; float: right;"></a>';
        navHref += '<a href="#" onclick="myViewer.nav(-1); return false;"><img src="' + this.navImgPrevious + '" style="border: 0px; float: right;"></a>';
    }
    nav.innerHTML = navHref;
    
    this.timerLoader = setInterval(function() {
        if (obj.countEnter > 10) {
            obj.showLoader();
        }
        obj.countEnter++;
    }, 50);
    
    firstImg.src = srcImg;
    this.curPos = key;
};

/** Функция анимации. **/
myViewer.animateCSS = function(element, numFrames, timePerFrame, animation, whendone) {
    var obj = this;
    this.flagAnimation = true;
    var frame = 0;
    var time = 0;
    
    this.timerAnimation = setInterval(function() {
        if (frame >= numFrames) {
            obj.flagAnimation = false;
            clearInterval(obj.timerAnimation);
            if (whendone) whendone(element);
            return;
        }
        for(var cssprop in animation) {
            try {
                element.style[cssprop] = animation[cssprop](frame, time, numFrames);
            } catch(e) {}
        }
        frame++;
        time += timePerFrame;
    }, timePerFrame);
};

/** Навигация. **/
myViewer.nav = function(pos) {
    if (this.flagAnimation == true) return;
    clearInterval(this.timerAuto);
    this.flagAuto = false;
    if (this.autolist) this.auto();
    this.list(pos);
};

/** Управление показом: 1 - вперед, -1 - назад. **/
myViewer.list = function(pos) {
    /** На одну картинку вперед. **/
    var tmp = this.curPos;
    if (pos == 1) {
        ++tmp;
        if (tmp > (this.listImages.length - 1)) tmp = 0;
        if (tmp < 0) tmp = 0;
    }
    /** На одну картинку назад. **/
    if (pos == -1) {
        --tmp;
        if (tmp < 0) tmp = this.listImages.length - 1;
        if (tmp > (this.listImages.length - 1)) tmp = this.listImages.length - 1;
    }   
    this.slideImage(tmp);
};

/** Сбросить все таймеры: эффекты, автоматическое пролистывание. **/
myViewer.resetAllTimer = function() {
    // Таймер пролистывания.
    clearInterval(this.timerAuto);
    this.flagAuto = false;
    // Скрываем загрузчик.
    clearInterval(this.timerLoader);
    if (this.showLoaderFlag) this.hideLoader();
    // Остановка эффекта.
    clearInterval(this.timerAnimation);
    this.flagAnimation = false;
};

/** Сбросить все таймеры: эффекты, автоматическое пролистывание. **/
myViewer.stop = function() {
    this.resetAllTimer();
};

myViewer.resizeImage = function(imgWidth, imgHeight, areaWidth, areaHeight) {
    if ((imgWidth > areaWidth) || (imgHeight > areaHeight)) {
        if (imgWidth > areaWidth) {
            var ratio = areaWidth / imgWidth;
            var newWidth = areaWidth;
            var newHeight = Math.ceil(imgHeight * ratio);
            if (newHeight > areaHeight) {
                ratio = areaHeight / imgHeight;
                newWidth = Math.ceil(imgWidth * ratio);
                newHeight = areaHeight;
            }
        } else if (imgHeight > areaHeight) {
            var ratio = areaHeight / imgHeight;
            var newWidth = Math.ceil(imgWidth * ratio);
            var newHeight = areaHeight;
            if (newWidth > areaWidth) {
                ratio = areaWidth / imgWidth;
                newHeight = Math.ceil(imgHeight * ratio);
                newWidth = areaWidth;
            }
        }
    } else {
        var newWidth = imgWidth;
        var newHeight = imgHeight;
    }
    return {width:newWidth, height:newHeight};
};


myViewer.boxFadeIn = function() {
    var box = document.getElementById(this.idBox);
    if (!box) return;
    
    if (box.style.opacity < 1) {
        var step = this.boxFadeInStep;
        var newOpacity = (100 * box.style.opacity) + step;  
        box.style.opacity = newOpacity / 100;
        box.style.filter = 'alpha(opacity=' + newOpacity + ')';
    } else {
        clearInterval(box.fadeInTimer);
    }
};

myViewer.boxFadeOut = function() {
    var box = document.getElementById(this.idBox);
    if (!box) return;
    
    if (box.style.opacity > 0) {
        var step = this.boxFadeOutStep;
        var newOpacity = (100 * box.style.opacity) - step;  
        box.style.opacity = newOpacity / 100;
        box.style.filter = 'alpha(opacity=' + newOpacity + ')';
    } else {
        clearInterval(box.fadeOutTimer);
        this.destroy();
    }
    
    clearInterval(this.timerAuto);
    // Скрываем загрузчик.
    clearInterval(this.timerLoader);
    // Остановка эффекта.
    clearInterval(this.timerAnimation);
};

/** Удалить объект просмотра. **/
myViewer.destroy = function() {
    var box = document.getElementById(this.idBox);
    if (box) box.parentNode.removeChild(box);
}

/** Закрыть окно просмотра. **/
myViewer.close = function() {
    this.stop();
    var box = document.getElementById(this.idBox);
    if (!box) return; 
    box.fadeOutTimer = setInterval(function(obj) {
        return function() {
            obj.boxFadeOut();
        };
    }(this), this.boxFadeOutTime);
};
