﻿function disableSelection(target) {
    if (typeof(target.onselectstart) != "undefined") //IE route
        target.onselectstart = function() { return false }
    else if (typeof(target.style.MozUserSelect) != "undefined") //Firefox route
        target.style.MozUserSelect = "none"
    else //All other route (ie: Opera)
        target.onmousedown = function() { return false }
    target.style.cursor = "default"
}

disableSelection(document.getElementById("view_area"));

function Zoom(url) {
    //image size returns from web service
    var size;

    //x, y is top left of tiles
    var x;
    var y;
    var z; //zoom level
    var maxZoom;
    
    var Width = 512;
    var Height = 512;
    var TileSize = 512;
    var Buffer = 0;

    //moving and dragging variables
    
    var Drag_StartX = 0;
    var Drag_StartY = 0;
    var ZoomBox_Dragging = false;
    var ZoomImage_Dragging = false;
    var Drag_Left;
    var Drag_Top;
    
    var Max;
    
    var ZoomImage = document.getElementById("ZoomImage");
    var ZoomImage_Cont = document.getElementById("ZoomImage_Cont");
    var MiniImage = document.getElementById("MiniImage");
    var ZoomBox = document.getElementById("ZoomBox");
    var ZoomBox_Cont = document.getElementById("ZoomBox_Cont");
    var Zoom_Control = document.getElementById("Zoom_Control");
    
    var tileBuffer = Object();

    var TileToQuadKey = function(tx, ty, zl)
    {
        var quad = "";
        for (var i = zl; i > 0; i--)
        {
            var mask = 1 << (i - 1);
            var cell = 0;
            if ((tx & mask) != 0)
            {
                cell++;
            }
            if ((ty & mask) != 0)
            {
                cell += 2;
            }
            quad += cell.toString();
        }
        return quad;
    };

    var Tile = function(tx, ty, zl) {
        var _Tile = this.Tile = document.createElement("DIV");
        _Tile.className = "Tile";
        _Tile.style.background = "url(img/ajax-loader.gif) no-repeat center center";

        var ImageUrl = "Tile.ashx?tx=" + tx + "&ty=" + ty + "&zl=" + z + "&url=" + escape(url);

        var Position = this.Position = function(x, y) {
            _Tile.style.left = x + "px";
            _Tile.style.top = y + "px";
        }

        var Resize = this.Resize = function(height, width) {
            _Tile.style.width = width + "px";
            _Tile.style.height = height + "px";
        }

        var Reset = this.Reset = function() {
            Position(-TileSize, -TileSize);
            Resize(TileSize, TileSize);
        }
        
        var _Image = this.Image = new Image();
        _Image.onload = function() {
            _Tile.innerHTML = "";
            Resize(TileSize, TileSize);
            _Tile.style.backgroundImage = "";

            var img = document.createElement("IMG");
            img.style.width = "100%";
            img.style.height = "100%";
            img.src = this.src;

            _Tile.appendChild(img);

            //_Tile.style.backgroundImage = "url(" + this.src + ")";
        }
        
        _Image.src = ImageUrl;
    }

    var renderLevel = function(x, y, z, Width, Height, TileSize, showup) {
        if (z > 1 && showup) {
            var upz = z >> 1;
            var upx = x;
            var upy = y;
            var upWidth = Width;
            var upHeight = Height;
            var upTile = TileSize * 2;
            renderLevel(upx, upy, upz, upWidth, upHeight, upTile, true);
        }

        var originX = Math.round(x - Width / 2);
        var originY = Math.round(y - Height / 2);

        // Calculate how much we need to shift the first tile (and
        // therefore all tiles) by to line up (originX, originY)
        // with the origin of the window.
        var drawingOffsetX = Math.round(originX % TileSize);
        var drawingOffsetY = Math.round(originY % TileSize);

        if (drawingOffsetX < 0)
            drawingOffsetX = Math.round(drawingOffsetX + TileSize);
        if (drawingOffsetY < 0)
            drawingOffsetY = Math.round(drawingOffsetY + TileSize);

        /*@cc_on
        drawingOffsetX += 256;
        @*/

        // Calculate the first and last tile indices needed to fill
        // the whole winodw.
        var txStart = Math.floor((originX - Buffer) / TileSize);
        var txEnd = Math.floor((originX + Width + Buffer) / TileSize);
        var tyStart = Math.floor((originY - Buffer) / TileSize);
        var tyEnd = Math.floor((originY + Height + Buffer) / TileSize);

        //txStart = Math.max(0, txStart);
        //tyStart = Math.max(0, tyStart);

        // Loop through all the tiles needed to fill the window.
        for (var tx = txStart; tx <= txEnd; tx++) {
            var drawingX = Math.round((tx - txStart) * TileSize - drawingOffsetX);
            for (var ty = tyStart; ty <= tyEnd; ty++) {
                var index = TileToQuadKey(tx, ty, z);

                var drawingY = Math.round((ty - tyStart) * TileSize - drawingOffsetY);

                //here we draw the images
                if (tileBuffer[index] == null) {
                    tileBuffer[index] = new Tile(tx, ty, z);
                    /*
                    //first let's check upward buffers
                    var upz = z >> 1;
                    var upx = Math.floor(tx / 2);
                    var upy = Math.floor(ty / 2);

                    var upIndex = TileToQuadKey(upx, upy, upz);

                    if (tileBuffer[upIndex] != null) {
                    //var dx = Math.round((upx - tx / 2) * 512);
                    //var dy = Math.round((upy - ty / 2) * 512);

                        var dx = (tx - txStart) * TileSize - drawingOffsetX - TileSize * 2 / z;
                    var dy = (ty - tyStart) * TileSize - drawingOffsetY - TileSize * 2 / z;

                        //populate the tile using the up index
                    tileBuffer[upIndex].Resize(2 * TileSize, 2 * TileSize);
                    //tileBuffer[upIndex].Position(drawingX + dx, drawingY + dy);
                    tileBuffer[upIndex].Position(dx, dy);
                    }*/

                    ZoomImage.appendChild(tileBuffer[index].Tile);
                }
                tileBuffer[index].Position(drawingX, drawingY);
                tileBuffer[index].Resize(TileSize, TileSize);
            }
        }
    }

    var render = this.render = function() {
        var originX = x - Width / 2;
        var originY = y - Height / 2;

        //position zoom box
        ZoomBox.style.height = Math.round(128 / z) + "px";
        ZoomBox.style.width = Math.round(128 / z) + "px";

        ZoomBox.style.left = Math.round((originX / z) / 4) + "px";
        ZoomBox.style.top = Math.round((originY / z) / 4) + "px";

        for (var i in tileBuffer) {
            //reset all tiles to defaults
            tileBuffer[i].Reset();
        }

        renderLevel(x, y, z, Width, Height, TileSize, true);
    }
    
    var Wrap = function(element)
    {
        var wrap = document.createElement("DIV");
        wrap.appendChild(element);
        return wrap;
    }

    var SetZoom = this.SetZoom = function(newZoom) {

        if (newZoom > maxZoom) return;
        if (newZoom < 1) return;

        Max = {
            "StartX": 256, "EndX": newZoom * TileSize - 256,
            "StartY": 256, "EndY": newZoom * TileSize - 256
        };

        x = x / z * newZoom;
        y = y / z * newZoom;
        if (x < Max.StartX) x = Max.StartX;
        if (x > Max.EndX) x = Max.EndX;
        if (y < Max.StartY) y = Max.StartY;
        if (y > Max.EndY) y = Max.EndY;

        z = newZoom;
        render();
    }

    ZoomImage.innerHTML = "Loading...";
    ZoomBox_Cont.style.display = "none";
    Zoom_Control.style.display = "none";
    
    //build image zoom info
    ImageZoom.ImageSize(url, function(s) {
        size = s;
        z = 1; //fit image in 512 block
        x = 256;
        y = 256;

        ZoomImage.innerHTML = "";
        render();

        if (Math.max(size.Width, size.Height) > 512) {

            maxZoom = Math.ceil(Math.max(size.Width, size.Height) / TileSize) << 1;

            Zoom_Control.innerHTML = "";

            var ZoomIn = document.createElement("A");
            ZoomIn.href = "Javascript:void(null);";
            ZoomIn.onclick = function(event) {
                SetZoom(z << 1);
            };

            ZoomIn.innerHTML = "<img src=\"img/087-zoom_in.gif\" alt=\"Zoom In\" />";

            var ZoomOut = document.createElement("A");
            ZoomOut.href = "Javascript:void(null);";
            ZoomOut.onclick = function(event) {
                SetZoom(z >> 1);
            };

            ZoomOut.innerHTML = "<img src=\"img/088-zoom_out.gif\" alt=\"Zoom Out\" />";

            Zoom_Control.appendChild(Wrap(ZoomIn));
            Zoom_Control.appendChild(Wrap(ZoomOut));

            Zoom_Control.style.display = "block";

            ZoomBox_Cont.style.display = "block";
            ZoomBox_Cont.style.backgroundImage =
                "url(Thumbnail.ashx?HEIGHT=128&WIDTH=128&URL=" + escape(url) + ")";

            ZoomBox.onmousedown = function(event) {
                Drag_StartX = Event.getMouseX(event);
                Drag_StartY = Event.getMouseY(event);
                ZoomBox_Dragging = true;
                Drag_Left = x;
                Drag_Top = y;

                Max = {
                    "StartX": 256, "EndX": z * TileSize - 256,
                    "StartY": 256, "EndY": z * TileSize - 256
                };
            }
        }
        else {
            Zoom_Control.style.display = "none";
        }

        //link up all of the events
        //ZoomImage_Cont.ondblclick = function(event) { };
        ZoomImage_Cont.onmousedown = function(event) {
            Drag_StartX = Event.getMouseX(event);
            Drag_StartY = Event.getMouseY(event);
            ZoomImage_Dragging = true;

            Drag_Left = x;
            Drag_Top = y;

            Max = {
                "StartX": 256, "EndX": z * TileSize - 256,
                "StartY": 256, "EndY": z * TileSize - 256
            };
        }

        document.body.onmouseup = function Drag_onmouseup(event) {
            ZoomBox_Dragging = false;
            ZoomImage_Dragging = false;
        };

        document.body.onmousemove = function(event) {
            var dx = Drag_StartX - Event.getMouseX(event);
            var dy = Drag_StartY - Event.getMouseY(event);

            if (ZoomBox_Dragging) {
                dx = dx * z * 4;
                dy = dy * z * 4;

                x = Drag_Left - dx;
                y = Drag_Top - dy;

                if (x < Max.StartX) x = Max.StartX;
                if (x > Max.EndX) x = Max.EndX;
                if (y < Max.StartY) y = Max.StartY;
                if (y > Max.EndY) y = Max.EndY;

                render();
            }

            if (ZoomImage_Dragging) {
                x = Drag_Left + dx;
                y = Drag_Top + dy;

                if (x < Max.StartX) x = Max.StartX;
                if (x > Max.EndX) x = Max.EndX;
                if (y < Max.StartY) y = Max.StartY;
                if (y > Max.EndY) y = Max.EndY;
                
                render();
            }
        }
    });
}
