﻿function FlowGallery() {
    this.defaults = {
        ratio: 1.964,
        imgcursor: 'pointer',
        FlowGalleryID: 'flowgallery',
        SideImgNum: 2,
        imagesHeight: 0.5,
        imagesM: 1.0,
        onClick: function () {
            $('.orderButton a').click();
        },
        opacity: [10, 7, 4],
        scaleLandscape: 203.6685,
        scaleOther: 100,
        buttonsWidth: 982,
        start: 3,
        step: 140
    };
    var thisObject = this;
    this.init = function (options) {
        var optionsArray = ['ratio', 'imgcursor', 'imagesM', 'FlowGalleryID', 'SideImgNum', 'imagesHeight', 'onClick', 'opacity', 'scaleLandscape', 'scaleOther', 'buttonsWidth', 'start', 'step'];
        var max = optionsArray.length;
        for (var i = 0; i < max; i++) {
            var name = optionsArray[i];
            this[name] = (options !== undefined && options[name] !== undefined) ? options[name] : thisObject.defaults[name]
        }
        var FlowGalleryDiv = document.getElementById(thisObject.FlowGalleryID);
        if (FlowGalleryDiv) {
            FlowGalleryDiv.style.visibility = 'visible';
            this.FlowGalleryDiv = FlowGalleryDiv;
            if (this.createStructure()) {
                this.imagesDiv = document.getElementById(thisObject.FlowGalleryID + '_images');
                this.captionDiv = document.getElementById(thisObject.FlowGalleryID + '_caption');
                this.navigationDiv = document.getElementById(thisObject.FlowGalleryID + '_navigation');
                this.scrollbarDiv = document.getElementById(thisObject.FlowGalleryID + '_scrollbar');
                this.buttonNextDiv = document.getElementById(thisObject.FlowGalleryID + '_next');
                this.buttonPreviousDiv = document.getElementById(thisObject.FlowGalleryID + '_previous');
                this.indexArray = [];
                this.current = 0;
                this.imageID = 0;
                this.target = 0;
                this.memTarget = 0;
                this.firstRefresh = true;
                this.firstCheck = true;
                this.busy = false;
                var width = this.FlowGalleryDiv.offsetWidth;
                var height = Math.round(width / thisObject.ratio);
                document.getElementById(thisObject.FlowGalleryID + '_loading_txt').style.paddingTop = ((height * 0.5) - 100) + 'px';
                FlowGalleryDiv.style.height = height + 'px';
                this.loadingProgress()
            }
        }
    };
    this.createStructure = function () {
        var imagesDiv = thisObject.Helper.createDocumentElement('div', 'images');
        var node = null;
        var max = this.FlowGalleryDiv.childNodes.length;
        for (var index = 0; index < max; index++) {
            node = this.FlowGalleryDiv.childNodes[index];
            if (node && node.nodeType == 1 && node.nodeName == 'IMG') {
                var imageNode = node.cloneNode(true);
                imagesDiv.appendChild(imageNode)
            }
        }
        var loadingP = thisObject.Helper.createDocumentElement('p', 'loading_txt');
        var loadingText = document.createTextNode(' ');
        loadingP.appendChild(loadingText);
        var loadingDiv = thisObject.Helper.createDocumentElement('div', 'loading');
        var loadingBarDiv = thisObject.Helper.createDocumentElement('div', 'loading_bar');
        loadingDiv.appendChild(loadingBarDiv);
        var captionDiv = thisObject.Helper.createDocumentElement('div', 'caption');
        var scrollbarDiv = thisObject.Helper.createDocumentElement('div', 'scrollbar');
        var buttonPreviousDiv = thisObject.Helper.createDocumentElement('div', 'previous', 'button');
        var buttonNextDiv = thisObject.Helper.createDocumentElement('div', 'next', 'button');
        scrollbarDiv.appendChild(buttonPreviousDiv);
        scrollbarDiv.appendChild(buttonNextDiv);
        var navigationDiv = thisObject.Helper.createDocumentElement('div', 'navigation');
        navigationDiv.appendChild(captionDiv);
        navigationDiv.appendChild(scrollbarDiv);
        var success = false;
        if (thisObject.FlowGalleryDiv.appendChild(imagesDiv) && thisObject.FlowGalleryDiv.appendChild(loadingP) && thisObject.FlowGalleryDiv.appendChild(loadingDiv) && thisObject.FlowGalleryDiv.appendChild(navigationDiv)) {
            for (index = 0; index < max; index++) {
                node = this.FlowGalleryDiv.childNodes[index];
                if (node && node.nodeType == 1 && node.nodeName == 'IMG') {
                    this.FlowGalleryDiv.removeChild(node)
                }
            }
            success = true
        }
        return success
    };
    this.loadingProgress = function () {
        var p = thisObject.loadingStatus();
        if (p < 100 || thisObject.firstCheck === true) {
            if (thisObject.firstCheck === true && p == 100) {
                thisObject.firstCheck = false;
                window.setTimeout(thisObject.loadingProgress, 100)
            } else {
                window.setTimeout(thisObject.loadingProgress, 40)
            }
        } else {
            document.getElementById(thisObject.FlowGalleryID + '_loading_txt').style.display = 'none';
            document.getElementById(thisObject.FlowGalleryID + '_loading').style.display = 'none';
            window.setTimeout(thisObject.Helper.addResizeEvent, 1000);
            thisObject.MouseWheel.init();
            thisObject.MouseDrag.init();
            thisObject.Touch.init();
            thisObject.Key.init();
            thisObject.refresh(true);
            document.getElementById(thisObject.FlowGalleryID + '_scrollbar').style.visibility = 'visible';
            var start = thisObject.start - 1;
            if (start < 0) {
                start = 0
            }
            if (start > thisObject.max) {
                start = thisObject.max - 1
            }
            thisObject.glideTo(start);
            thisObject.moveTo(5000)
        }
    };
    this.loadingStatus = function () {
        var max = thisObject.imagesDiv.childNodes.length;
        var i = 0,
            completed = 0;
        var image = null;
        for (var index = 0; index < max; index++) {
            image = thisObject.imagesDiv.childNodes[index];
            if (image && image.nodeType == 1 && image.nodeName == 'IMG') {
                if (image.complete === true) {
                    completed++
                }
                i++
            }
        }
        var finished = Math.round((completed / i) * 100);
        var loadingBar = document.getElementById(thisObject.FlowGalleryID + '_loading_bar');
        loadingBar.style.width = finished + '%';
        var loadingP = document.getElementById(thisObject.FlowGalleryID + '_loading_txt');
        var loadingTxt = document.createTextNode('Загрузка изображений: ' + completed + '/' + i);
        loadingP.replaceChild(loadingTxt, loadingP.firstChild);
        return finished
    };
    this.refresh = function () {
        this.imagesDivWidth = thisObject.imagesDiv.offsetWidth + thisObject.imagesDiv.offsetLeft;
        this.maxHeight = Math.round(thisObject.imagesDivWidth / thisObject.ratio);
        this.maxFocus = thisObject.SideImgNum * thisObject.step;
        this.size = thisObject.imagesDivWidth * 0.5;
        this.imagesDivHeight = Math.round(thisObject.maxHeight * thisObject.imagesHeight);
        thisObject.FlowGalleryDiv.style.height = thisObject.maxHeight + 'px';
        thisObject.imagesDiv.style.height = thisObject.imagesDivHeight + 'px';
        thisObject.navigationDiv.style.height = (thisObject.maxHeight - thisObject.imagesDivHeight) + 'px';
        thisObject.captionDiv.style.width = thisObject.imagesDivWidth + 'px';
        thisObject.captionDiv.style.paddingTop = '0px';
        thisObject.scrollbarDiv.style.width = thisObject.buttonsWidth + 'px';
        thisObject.scrollbarDiv.style.marginTop = Math.round(thisObject.imagesDivWidth * 0.02) + 'px';
        thisObject.scrollbarDiv.style.marginLeft = Math.round(((thisObject.imagesDivWidth - thisObject.buttonsWidth) / 2)) + 'px';
        thisObject.buttonPreviousDiv.onclick = function () {
            thisObject.MouseWheel.handle(1)
        };
        thisObject.buttonNextDiv.onclick = function () {
            thisObject.MouseWheel.handle(-1)
        };
        var multi = 1;
        var max = thisObject.imagesDiv.childNodes.length;
        var i = 0;
        var image = null;
        for (var index = 0; index < max; index++) {
            image = thisObject.imagesDiv.childNodes[index];
            if (image !== null && image.nodeType == 1 && image.nodeName == 'IMG') {
                this.indexArray[i] = index;
                image.url = image.getAttribute('longdesc');
                image.xPosition = (-i * thisObject.step);
                image.i = i;
                if (thisObject.firstRefresh) {
                    if (image.getAttribute('width') !== null && image.getAttribute('height') !== null) {
                        image.w = image.getAttribute('width');
                        image.h = image.getAttribute('height') * multi
                    } else {
                        image.w = image.width;
                        image.h = image.height
                    }
                }
                if ((image.w) > (image.h / 1.5)) {
                    image.pc = thisObject.scaleLandscape;
                    image.pcMem = thisObject.scaleLandscape
                } else {
                    image.pc = thisObject.scaleOther;
                    image.pcMem = thisObject.scaleOther
                }
                image.style.cursor = thisObject.imgcursor;
                i++
            }
        }
        this.max = thisObject.indexArray.length;
        if (thisObject.firstRefresh) {
            thisObject.firstRefresh = false
        }
        thisObject.glideTo(thisObject.imageID);
        thisObject.moveTo(thisObject.current)
    };
    this.moveTo = function (x) {
        this.current = x;
        this.zIndex = thisObject.max;
        for (var index = 0; index < thisObject.max; index++) {
            var image = thisObject.imagesDiv.childNodes[thisObject.indexArray[index]];
            var currentImage = index * -thisObject.step;
            if ((currentImage + thisObject.maxFocus) < thisObject.memTarget || (currentImage - thisObject.maxFocus) > thisObject.memTarget) {
                image.style.visibility = 'hidden';
                image.style.display = 'none'
            } else {
                var z = (Math.sqrt(10000 + x * x) + 100) * thisObject.imagesM;
                var xs = x / z * thisObject.size + thisObject.size;
                image.style.display = 'block';
                var newImageH = (image.h / image.w * image.pc) / z * thisObject.size;
                var newImageW = image.pc / z * thisObject.size;
                var newImageTop = ((thisObject.imagesDivHeight - newImageH) + ((newImageH / 1.5) * 0.5))*1.3;
                image.style.left = xs - (image.pc / 2) / z * thisObject.size + 'px';
                if (newImageW && newImageH) {
                    image.style.height = newImageH + 'px';
                    image.style.width = newImageW + 'px';
                    image.style.top = newImageTop + 'px'
                }
                image.style.visibility = 'visible';
                switch (x < 0) {
                case true:
                    this.zIndex++;
                    break;
                default:
                    this.zIndex = thisObject.zIndex - 1;
                    break
                }
                switch (image.i == thisObject.imageID) {
                case false:
                    image.onclick = function () {
                        thisObject.glideTo(this.i)
                    };
                    break;
                default:
                    this.zIndex = thisObject.zIndex + 1;
                    if (image.url !== '') {
                        image.onclick = thisObject.onClick
                    }
                    break
                }
                image.style.zIndex = thisObject.zIndex
            }
            x += thisObject.step
        }
    };
    this.glideTo = function (imageID) {
        var x = -imageID * thisObject.step;
        this.target = x;
        this.memTarget = x;
        this.imageID = imageID;
        var caption = thisObject.imagesDiv.childNodes[imageID].getAttribute('alt');
        thisObject.captionDiv.innerHTML = '<div class="orderButton"><a href="' + thisObject.imagesDiv.childNodes[imageID].getAttribute('longdesc') + '" title="'+ caption +'">' + caption + '</a></div>';
        thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[imageID], thisObject.opacity[0]);
        thisObject.imagesDiv.childNodes[imageID].pc = thisObject.imagesDiv.childNodes[imageID].pc;
        var opacityValue = 0;
        var rightID = 0;
        var leftID = 0;
        var last = thisObject.opacity.length;
        for (var i = 1; i < (thisObject.SideImgNum + 1); i++) {
            if ((i + 1) > last) {
                opacityValue = thisObject.opacity[last - 1]
            } else {
                opacityValue = thisObject.opacity[i]
            }
            rightID = imageID + i;
            leftID = imageID - i;
            if (rightID < thisObject.max) {
                thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[rightID], opacityValue);
                thisObject.imagesDiv.childNodes[rightID].pc = thisObject.imagesDiv.childNodes[rightID].pcMem
            }
            if (leftID >= 0) {
                thisObject.Helper.setOpacity(thisObject.imagesDiv.childNodes[leftID], opacityValue);
                thisObject.imagesDiv.childNodes[leftID].pc = thisObject.imagesDiv.childNodes[leftID].pcMem
            }
        }
        if (thisObject.busy === false) {
            window.setTimeout(thisObject.animate, 50);
            thisObject.busy = true
        }
    };
    this.animate = function () {
        switch (thisObject.target < thisObject.current - 1 || thisObject.target > thisObject.current + 1) {
        case true:
            thisObject.moveTo(thisObject.current + (thisObject.target - thisObject.current) / 3);
            window.setTimeout(thisObject.animate, 50);
            thisObject.busy = true;
            break;
        default:
            thisObject.busy = false;
            break
        }
    };
    this.MouseWheel = {
        init: function () {
            if (window.addEventListener) {
                thisObject.FlowGalleryDiv.addEventListener('DOMMouseScroll', thisObject.MouseWheel.get, false)
            }
            thisObject.Helper.addEvent(thisObject.FlowGalleryDiv, 'mousewheel', thisObject.MouseWheel.get)
        },
        get: function (event) {
            var delta = 0;
            if (!event) {
                event = window.event
            }
            if (event.wheelDelta) {
                delta = event.wheelDelta / 120
            } else if (event.detail) {
                delta = -event.detail / 3
            }
            if (delta) {
                thisObject.MouseWheel.handle(delta)
            }
            thisObject.Helper.suppressBrowserDefault(event)
        },
        handle: function (delta) {
            var change = false;
            var newImageID = 0;
            if (delta > 0) {
                if (thisObject.imageID >= 1) {
                    newImageID = thisObject.imageID - 1;
                    change = true
                }
            } else {
                if (thisObject.imageID < (thisObject.max - 1)) {
                    newImageID = thisObject.imageID + 1;
                    change = true
                }
            }
            if (change === true) {
                thisObject.glideTo(newImageID)
            }
        }
    };
    this.MouseDrag = {
        object: null,
        objectX: 0,
        mouseX: 0,
        newX: 0,
        busy: false,
        init: function () {
            thisObject.Helper.addEvent(thisObject.FlowGalleryDiv, 'mousemove', thisObject.MouseDrag.drag);
            thisObject.Helper.addEvent(thisObject.FlowGalleryDiv, 'mouseup', thisObject.MouseDrag.stop);
            thisObject.Helper.addEvent(document, 'mouseup', thisObject.MouseDrag.stop);
            thisObject.FlowGalleryDiv.onselectstart = function () {
                var selection = true;
                if (thisObject.MouseDrag.busy === true) {
                    selection = false
                }
                return selection
            }
        },
        start: function (o) {
            thisObject.MouseDrag.object = o;
            thisObject.MouseDrag.objectX = thisObject.MouseDrag.mouseX - o.offsetLeft
        },
        stop: function () {
            thisObject.MouseDrag.object = null;
            thisObject.MouseDrag.busy = false
        },
        drag: function (e) {
            var posx = 0;
            if (!e) {
                e = window.event
            }
            if (e.pageX) {
                posx = e.pageX
            } else if (e.clientX) {
                posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft
            }
            thisObject.MouseDrag.mouseX = posx
        }
    };
    this.Touch = {
        x: 0,
        startX: 0,
        stopX: 0,
        busy: false,
        first: true,
        init: function () {
            thisObject.Helper.addEvent(thisObject.navigationDiv, 'touchstart', thisObject.Touch.start);
            thisObject.Helper.addEvent(document, 'touchmove', thisObject.Touch.handle);
            thisObject.Helper.addEvent(document, 'touchend', thisObject.Touch.stop)
        },
        isOnNavigationDiv: function (e) {
            var state = false;
            if (e.touches) {
                var target = e.touches[0].target;
                if (target === thisObject.navigationDiv || target === thisObject.scrollbarDiv) {
                    state = true
                }
            }
            return state
        },
        getX: function (e) {
            var x = 0;
            if (e.touches) {
                x = e.touches[0].pageX
            }
            return x
        },
        start: function (e) {
            thisObject.Touch.startX = thisObject.Touch.getX(e);
            thisObject.Touch.busy = true;
            thisObject.Helper.suppressBrowserDefault(e)
        },
        isBusy: function () {
            var busy = false;
            if (thisObject.Touch.busy === true) {
                busy = true
            }
            return busy
        },
        handle: function (e) {
            if (thisObject.Touch.isBusy && thisObject.Touch.isOnNavigationDiv(e)) {
                if (thisObject.Touch.first) {
                    thisObject.Touch.stopX = ((thisObject.max - 1) - thisObject.imageID) * (thisObject.imagesDivWidth / (thisObject.max - 1));
                    thisObject.Touch.first = false
                }
                var newX = -(thisObject.Touch.getX(e) - thisObject.Touch.startX - thisObject.Touch.stopX);
                if (newX < 0) {
                    newX = 0
                }
                if (newX > thisObject.imagesDivWidth) {
                    newX = thisObject.imagesDivWidth
                }
                thisObject.Touch.x = newX;
                var imageID = Math.round(newX / (thisObject.imagesDivWidth / (thisObject.max - 1)));
                imageID = (thisObject.max - 1) - imageID;
                if (thisObject.imageID !== imageID) {
                    thisObject.glideTo(imageID)
                }
                thisObject.Helper.suppressBrowserDefault(e)
            }
        },
        stop: function () {
            thisObject.Touch.stopX = thisObject.Touch.x;
            thisObject.Touch.busy = false
        }
    };
    this.Key = {
        init: function () {
            document.onkeydown = function (event) {
                thisObject.Key.handle(event)
            }
        },
        handle: function (event) {
            var charCode = thisObject.Key.get(event);
            switch (charCode) {
            case 39:
                thisObject.MouseWheel.handle(-1);
                break;
            case 37:
                thisObject.MouseWheel.handle(1);
                break
            }
        },
        get: function (event) {
            event = event || window.event;
            return event.keyCode
        }
    };
    this.Helper = {
        addEvent: function (obj, type, fn) {
            if (obj.addEventListener) {
                obj.addEventListener(type, fn, false)
            } else if (obj.attachEvent) {
                obj["e" + type + fn] = fn;
                obj[type + fn] = function () {
                    obj["e" + type + fn](window.event)
                };
                obj.attachEvent("on" + type, obj[type + fn])
            }
        },
        setOpacity: function (object, value) {
            object.style.opacity = value / 10;
            object.style.filter = 'alpha(opacity=' + value * 10 + ')'
        },
        createDocumentElement: function (type, id, optionalClass) {
            var element = document.createElement(type);
            element.setAttribute('id', thisObject.FlowGalleryID + '_' + id);
            if (optionalClass !== undefined) {
                id += ' ' + optionalClass
            }
            element.setAttribute('class', id);
            element.setAttribute('className', id);
            return element
        },
        suppressBrowserDefault: function (e) {
            if (e.preventDefault) {
                e.preventDefault()
            } else {
                e.returnValue = false
            }
            return false
        },
        addResizeEvent: function () {
            var otherFunctions = window.onresize;
            if (typeof window.onresize != 'function') {
                window.onresize = function () {
                    thisObject.refresh()
                }
            } else {
                window.onresize = function () {
                    if (otherFunctions) {
                        otherFunctions()
                    }
                    thisObject.refresh()
                }
            }
        }
    }
}
var domReadyEvent = {
    name: "domReadyEvent",
    events: {},
    domReadyID: 1,
    bDone: false,
    DOMContentLoadedCustom: null,
    add: function (handler) {
        if (!handler.$$domReadyID) {
            handler.$$domReadyID = this.domReadyID++;
            if (this.bDone) {
                handler()
            }
            this.events[handler.$$domReadyID] = handler
        }
    },
    remove: function (handler) {
        if (handler.$$domReadyID) {
            delete this.events[handler.$$domReadyID]
        }
    },
    run: function () {
        if (this.bDone) {
            return
        }
        this.bDone = true;
        for (var i in this.events) {
            this.events[i]()
        }
    },
    schedule: function () {
        if (this.bDone) {
            return
        }
        if (/KHTML|WebKit/i.test(navigator.userAgent)) {
            if (/loaded|complete/.test(document.readyState)) {
                this.run()
            } else {
                setTimeout(this.name + ".schedule()", 100)
            }
        } else if (document.getElementById("__ie_onload")) {
            return true
        }
        if (typeof this.DOMContentLoadedCustom === "function") {
            if (typeof document.getElementsByTagName !== 'undefined' && (document.getElementsByTagName('body')[0] !== null || document.body !== null)) {
                if (this.DOMContentLoadedCustom()) {
                    this.run()
                } else {
                    setTimeout(this.name + ".schedule()", 250)
                }
            }
        }
        return true
    },
    init: function () {
        if (document.addEventListener) {
            document.addEventListener("DOMContentLoaded", function () {
                domReadyEvent.run()
            }, false)
        }
        setTimeout("domReadyEvent.schedule()", 100);

        function run() {
            domReadyEvent.run()
        }
        if (typeof addEvent !== "undefined") {
            addEvent(window, "load", run)
        } else if (document.addEventListener) {
            document.addEventListener("load", run, false)
        } else if (typeof window.onload === "function") {
            var oldonload = window.onload;
            window.onload = function () {
                domReadyEvent.run();
                oldonload()
            }
        } else {
            window.onload = run
        } /*@cc_on@if(@_win32||@_win64)document.write("<script id=__ie_onload defer src=\"//:\"><\/script>");var script=document.getElementById("__ie_onload");script.onreadystatechange=function(){if(this.readyState=="complete"){domReadyEvent.run()}};@end@*/
    }
};
var domReady = function (handler) {
        domReadyEvent.add(handler)
    };
domReadyEvent.init();
domReady(function () {
    var instanceOne = new FlowGallery();
    instanceOne.init({
        FlowGalleryID: 'flowgallery'
    })
});
