﻿var distanceSet = false;
var mouseObjectDeltaX = 0;
var mouseObjectDeltaY = 0;
var scrollXOffset = 0;
var scrollYOffset = 0;

var imageWidth = 0;
var imageHeight = 0;
var originalWidth = 0;
var originalHeight = 0;
var mouseInitialX = 0;
var mouseInitialY = 0;
var MAX_IMAGE_WIDTH = 750;
var MAX_IMAGE_HEIGHT = 600;
var MIN_IMAGE_WIDTH = 10;
var MIN_IMAGE_HEIGHT = 10;

var mouseDown = false;
var dragTarget = null;

var loadingDiv = null;
var updatePanelDiv = null;
var designImgDiv = null;
var imageBoundingDiv = null;
var resizeImg = null;
var designImg = null;
var constrainBox = null;
var resetBtn = null;

// An array of all DraggableObjects
var allDraggableObjects = null;

// This is a nice wrapper class that takes elements that we want to be draggable and
// wraps them in a class that contains a function for determining whether or not
// the coordinates given are over the element. Putting elements in a class like this
// allows us to then put them in an array and iterate through the array calling the
// IsOver function for each.  It also allows for easier modularity and adding/removing
// draggable elements.
DraggableObject = function(e) {
    this.foo = e;
    // Returns true if the mouse coordinates given are over the box
}

// In game programming we put a bounding box around something for collision detection and ray intersecting.
// We need to do something similar to each draggable object to determin if the mouse is over it so the 
// bounding box is represented by the top and left coordinates and the right and bottom coordinates.
// To get the bottom and right coordinates we add the width and height to the left and top coordinates
// respectively to get the right and bottom coordinates
// (left, top)
//        +==================+ |
//        |                  | |  Top
//        |                  | |   +
//        |                  | | Height
//        +==================+ \/
//        ----Left +Width---->
// We know that if the cooridantes are greater than or equal to the left and top coordinates 
// but less than or equal to the right and bottom coordinates then the mouse is over it so return true.
// Making a prototype means that memory is only initialized once for this function.
DraggableObject.prototype.IsOver = function(mouseX, mouseY) {
    return (mouseX >= GetXPos(this.foo) && mouseX <= GetXPos(this.foo) + this.foo.offsetWidth && mouseY >= GetYPos(this.foo) && mouseY <= GetYPos(this.foo) + this.foo.offsetHeight);
};

function Initialize() {
    // We want these objects in order of top to bottom
    if (loadingDiv == null) {
        loadingDiv = document.getElementById("loadingDiv");
    }
    if(updatePanelDiv == null)
    {
        updatePanelDiv = document.getElementById("updatePanelDiv");
    }
    if(designImgDiv == null)
    {
        designImgDiv = document.getElementById("designImgDiv");
    }
    if(imageBoundingDiv == null)
    {
        imageBoundingDiv = document.getElementById("imageBoundingDiv");
    }
    if(resizeImg == null)
    {
        resizeImg = document.getElementById("resizeImg");
    }
    if(designImg == null)
    {
        designImg = document.getElementById("designImg");
        GetOriginalImageProperties();
    }
    if(constrainBox == null)
    {
        constrainBox = document.getElementById("constrainBox");
    }
    if(resetBtn == null)
    {
        resetBtn = document.getElementById("resetBtn");
    }
    
    var draggableObjects = new Array(updatePanelDiv, resizeImg, designImgDiv);
                            
    allDraggableObjects = new Array(draggableObjects.length);
    // Create an array of all draggable objects and store them into our class
    for (var i = 0; i < draggableObjects.length; i++) {
        allDraggableObjects[i] = new DraggableObject(draggableObjects[i]);
    }
}


function ResetAll()
{
    //designImg.style.width = originalWidth;
    //designImg.style.height = originalHeight;
    designImg.style.width = designImg.style.height = "";
    designImgDiv.style.left = "0px";
    designImgDiv.style.top = "0px";
    UpdateImageBoundingDiv();
}


function GetOriginalImageProperties()
{
    var tempImg = new Image();
    tempImg.src = designImg.src;
    originalWidth = tempImg.width;
    originalHeight = tempImg.height;
}


function GetImageProperties()
{
    imageWidth = parseInt(designImg.offsetWidth);
    imageHeight = parseInt(designImg.offsetHeight);
}


// Sets the image bounding div to the constraints of the design image
function UpdateImageBoundingDiv()
{
    imageBoundingDiv.style.left = parseInt(designImgDiv.offsetLeft) + "px";
    imageBoundingDiv.style.top = parseInt(designImgDiv.offsetTop) + "px";
    imageBoundingDiv.style.width = parseInt(designImgDiv.offsetWidth) - 2 + "px";
    imageBoundingDiv.style.height = parseInt(designImgDiv.offsetHeight) - 2 + "px";
}

// When getting the position of an element the "offsetLeft/Top" will return
// coordinates based of any parent with relative positioning set so this
// function gets the coordinates of any parent container that might have relative
// positioning set and addes it to the current element's coordinates to give us
// coordinates relative to the page rather than any parent container
function GetXPos(element) {
    var x = 0;
    while (element != null) {
        x += element.offsetLeft;
        element = element.offsetParent;
    }
    return x;
}

function GetYPos(element) {
    var y = 0;
    while (element != null) {
        y += element.offsetTop;
        element = element.offsetParent;
    }
    return y;
}

// The mouse coordinates are relative to the screen (window) and not to the page
// so if we are scrolled, the top left of the viewable window will be 0, 0 and not
// the page so we add in the scroll offsets to account for this
function GetScrollOffsets() {
    if (document.all) {
        if (document.documentElement) {
            scrollXOffset = document.documentElement.scrollLeft;
            scrollYOffset = document.documentElement.scrollTop;
        }
        else {
            scrollXOffset = document.body.scrollLeft;
            scrollYOffset = document.body.scrollTop;
        }
    }
    else{
        scrollXOffset = window.pageXOffset;
        scrollYOffset = window.pageYOffset;
    }
}

function HideLoadingDiv() {
    if (loadingDiv == null) {
        loadingDiv = document.getElementById("loadingDiv");
    }
    loadingDiv.style.visibility = 'hidden';
    loadingDiv.style.display = 'none';
}

function ShowLoadingDiv() {
    loadingDiv.style.visibility = 'visible';
    loadingDiv.style.display = 'block';
}

window.onload = function() {
    Initialize();

    UpdateImageBoundingDiv();
    GetImageProperties();
    resetBtn.onclick = ResetAll;
    designImg.onload = HideLoadingDiv;
    HideLoadingDiv();

    // When the mouse is down we're gonna check to see if we're over one of
    // two draggable objects by getting their bounding box. (top, left, width, height)
    // Perhaps we can make it modular by making a draggable object class which has these
    // attributes and a function to check to see if the mouse is over it.  Let's see!
    document.onmousedown = function(e) {
        // Get page scroll offsets
        GetScrollOffsets();

        // Mouse button is down so get the mouse coordinates and pass them into
        // each draggable object and see if it's over any of them
        dragTarget = null;
        //document.getElementById("foo1Txt").value = scrollXOffset + " -- " + allDraggableObjects[0].foo.offsetWidth + " x " + allDraggableObjects[0].foo.offsetHeight + " (" + GetXPos(allDraggableObjects[0].foo) + "," + GetYPos(allDraggableObjects[0].foo) + ")";
        //document.getElementById("foo2Txt").value = scrollYOffset + " -- " + allDraggableObjects[1].foo.offsetWidth + " x " + allDraggableObjects[1].foo.offsetHeight + " (" + GetXPos(allDraggableObjects[1].foo) + "," + GetYPos(allDraggableObjects[1].foo) + ")";
        var mouseX = document.all ? parseInt(event.clientX) : parseInt(e.clientX);
        var mouseY = document.all ? parseInt(event.clientY) : parseInt(e.clientY);

        // We go through this loop until we iterated through each possible draggable object
        // or until we find one that the mouse is over
        for (var i = 0; i < allDraggableObjects.length && dragTarget == null; i++) {
            // Pass in the mouse coordinates (accounting for scroll offset) into each DraggableObject
            // in the array and check to see if it returns true that the mouse is over it
            if (allDraggableObjects[i].IsOver(mouseX + scrollXOffset, mouseY + scrollYOffset)) {
                // Mouse is over the object so set it as the drag target and break from the for-loop
                dragTarget = allDraggableObjects[i].foo;
                break;
            }
        }

        // If we found one then enable dragging
        if (dragTarget != null) {
            if (dragTarget.id == "resizeImg") {
                mouseDown = true;
                document.onmousemove = ResizeImage;
                return false;
            }
            else {
                mouseDown = true;
                document.onmousemove = DragObject;
                return false;
            }
        }
        else {
            document.onmousemove = null;
            mouseDown = false;
        }
    };

    // When the mouse is released we disable dragging (represented by mouseDown boolean variable)
    document.onmouseup = function() {
        mouseDown = false;
        distanceSet = false;
        document.getElementById("mySpecialDiv").style.cursor = "default"
        document.onmousemove = null;
    };

}

// We check to see if dragging is enabled and if we have a drag target
// and then move the target
function DragObject(e) {
    if (mouseDown && dragTarget != null) {
        // Change the cursor to the move cursor
        document.getElementById("mySpecialDiv").style.cursor = "move";

        //Get mouse position relative to window
        var mouseX = document.all ? parseInt(event.clientX) : parseInt(e.clientX);
        var mouseY = document.all ? parseInt(event.clientY) : parseInt(e.clientY);

        //Get the position of the drag object relative to the window
        var dragTargetX = parseInt(dragTarget.offsetLeft);
        var dragTargetY = parseInt(dragTarget.offsetTop);

        // Find the difference between the drag object position and the mouse position
        // from when the mouse is clicked and moving is enabled
        // We store this distance so that it keeps the drag object top left that far away from
        // the mouse as we move
        if (!distanceSet) {
            mouseObjectDeltaX = mouseX - dragTargetX;
            mouseObjectDeltaY = mouseY - dragTargetY;
            distanceSet = true;
        }

        //Set the position of the drag object
        var positionX = mouseX - mouseObjectDeltaX;
        var positionY = mouseY - mouseObjectDeltaY;

        dragTarget.style.left = positionX + "px";
        dragTarget.style.top = positionY + "px";
        
        UpdateImageBoundingDiv();
        return false;
    }
    else {
        // Change the cursor back to default
        document.getElementById("mySpecialDiv").style.cursor = "default"
    }
}


function ResizeImage(e)
{
    if(mouseDown && dragTarget.id == "resizeImg")
    {
        document.getElementById("mySpecialDiv").style.cursor = "nw-resize";
        
        //Get mouse position relative to window
        var mouseX = document.all ? parseInt(event.clientX) : parseInt(e.clientX);
        var mouseY = document.all ? parseInt(event.clientY) : parseInt(e.clientY);

        //Get the position of the drag object relative to the window
        var dragTargetX = parseInt(dragTarget.offsetLeft);
        var dragTargetY = parseInt(dragTarget.offsetTop);

        // Find the difference between the drag object position and the mouse position
        // from when the mouse is clicked and moving is enabled
        // We store this distance so that it keeps the drag object top left that far away from
        // the mouse as we move
        if (!distanceSet) {
            GetImageProperties();
            mouseInitialX = mouseX;
            mouseInitialY = mouseY;
            //mouseObjectDeltaX = mouseX - dragTargetX;
            //mouseObjectDeltaY = mouseY - dragTargetY;
            distanceSet = true;
        }
        
        var width = 0;
        var height = 0;
        
        // Get the change in position from when the mouse was first clicked
        var deltaX = mouseX - mouseInitialX;
        var deltaY = mouseY - mouseInitialY;
        
        if(constrainBox.checked)
        {
            var delta = Math.floor((deltaX + deltaY) / 2);
            width = delta + imageWidth;
            height = delta + imageHeight;
            
            // Check image for max and min sizes
            if(width < MIN_IMAGE_WIDTH)
            {
                height += MIN_IMAGE_WIDTH - width;
                width = MIN_IMAGE_WIDTH;
            }
            else if(height < MIN_IMAGE_HEIGHT)
            {
                width += MIN_IMAGE_HEIGHT - height;
                height = MIN_IMAGE_HEIGHT;
            }
            else if(width > MAX_IMAGE_WIDTH)
            {
                height -= width - MAX_IMAGE_WIDTH;
                width = MAX_IMAGE_WIDTH;
            }
            else if(height > MAX_IMAGE_HEIGHT)
            {
                width -= height - MAX_IMAGE_HEIGHT;
                height = MAX_IMAGE_HEIGHT;
            }
        }
        else
        {
            // Non-proportionate resizing
            width = deltaX + imageWidth;
            height = deltaY + imageHeight;
            
            // Check image for max and min sizes
            if(width < MIN_IMAGE_WIDTH)
                width = MIN_IMAGE_WIDTH;
            if(height < MIN_IMAGE_HEIGHT)
                height = MIN_IMAGE_HEIGHT;
            if(width > MAX_IMAGE_WIDTH)
                width = MAX_IMAGE_WIDTH;
            if(height > MAX_IMAGE_HEIGHT)
                height = MAX_IMAGE_HEIGHT;
        }
        
        designImg.style.width = width + "px";
        designImg.style.height = height + "px";
        
        UpdateImageBoundingDiv();
        return false;
    }
    else {
        // Change the cursor back to default
        document.getElementById("mySpecialDiv").style.cursor = "default"
    }
}

function changeTemplate(imageURL) {
    document.getElementById("carTemplateImg").src = imageURL;
}

function changeTemplateImg(foo) {
    ShowLoadingDiv();
    designImg.src = foo;
    //document.getElementById("designImg").src = foo;
    GetOriginalImageProperties();
    UpdateImageBoundingDiv();
}

function scale() {
    var value = parseInt(document.getElementById("scaleTxt").innerText);
    document.getElementById("designImg").style.width = value + "%";
    document.getElementById("designImg").style.height = value + "%";
}

function colorChanged2(sender) {
    sender.get_element().style.color = "#" + sender.get_selectedColor();
    document.getElementById("mySpecialDiv").style.backgroundColor = "#" + sender.get_selectedColor();
}
function colorChanged2Alt(color) {
    document.getElementById("mySpecialDiv").style.backgroundColor = "#" + color;
}