function getX(event)
{
    return event.pageX - canvas_offset_x;
}

function getY(event)
{
    return event.pageY - canvas_offset_y;
}

function line(x1, y1, x2, y2, context)
{
    //alert(x1 + "," + y1 + "---" + x2 + "," + y2)
    if (x1 == x2 && y1 == y2)
    {
        var r = Number($("#line_width").val()) / 2;
        //Make a circle around x1,y1:
        context.beginPath();
        context.arc(x1+0.5, y1+0.5, r, 0.001, 0, false);
        context.fill();
    }
    else
    {
        context.beginPath();
        
        context.moveTo(x1, y1);
        context.lineTo(x2, y2);
        context.stroke();
    }
}

function rotateX(x, y, theta)
{
    var centerX = Number($("#center_x").val());
    var centerY = Number($("#center_y").val());
    x -= centerX
    y -= centerY

    return centerX + x * Math.cos(theta) - y * Math.sin(theta)
}

function rotateY(x, y, theta)
{
    var centerX = Number($("#center_x").val());
    var centerY = Number($("#center_y").val());

    x -= centerX
    y -= centerY

    return centerY + x * Math.sin(theta) + y * Math.cos(theta)
}

function rotatedLines(x1, y1, x2, y2, n, context)
{
    var centerX = Number($("#center_x").val());
    var centerY = Number($("#center_y").val());
    for (var i = 0; i < n; i++)
    {
        context.save()
        var theta = i * 2 * Math.PI / n
        context.translate(centerX, centerY)
        context.rotate(theta)
        context.translate(-centerX, -centerY)
        line(x1, y1, x2, y2, context)
        context.restore()
    }
}

function lines(x1, y1, x2, y2, context)
{
    var centerX = Number($("#center_x").val());

    var n = $("#rotate").val();
    var m = $("#mirror:checked").length;

    if (m)
    {
        rotatedLines(x1, y1, x2, y2, n, context)
        rotatedLines(2*centerX - x1, y1, 2*centerX - x2, y2, n, context)
    }
    else
    {
        rotatedLines(x1, y1, x2, y2, n, context)
    }
}

function enable_undo()
{
    $("#undo").removeAttr("disabled")
}

function disable_undo()
{
    $("#undo").attr("disabled", "disabled")
}

penTool = {
    imgSrc: "pen.png",
    hidesWorkingCanvas: false,
    
    draw: function(event)
    {
        var x = getX(event);
        var y = getY(event);
        
        updateColor(workingContext);
        
        lines(lastX, lastY, x, y, workingContext)
        lastX = x
        lastY = y
        
        enable_undo()
    },
    
    commit: function()
    {
        activeLayer.context.globalAlpha = 1;
        activeLayer.context.globalCompositeOperation = "source-over";
        activeLayer.context.drawImage($('#working_canvas')[0], 0, 0);
    },
    
    prepare: function()
    {
        workingContext.clearRect(0, 0, canvasWidth, canvasHeight);
        
        if (navigator.appName == "Opera")
        {
            workingContext.globalCompositeOperation = "source-over";
        }
        else
        {
            workingContext.globalCompositeOperation = "copy";
        }
    },
    
    undo: function()
    {
        workingContext.clearRect(0, 0, canvasWidth, canvasHeight);
        disable_undo()
    }
};

fillTool = {
    imgSrc: "pen.png",
    hidesWorkingCanvas: false,
    
    draw: function()
    {
        workingContext.fillStyle = $("#color_preview").css("backgroundColor");
        workingContext.globalAlpha = $("#alpha").val() / 100;
        workingContext.fillRect(0, 0, canvasWidth, canvasHeight);
        
        enable_undo()
    },
    
    commit: function()
    {
        activeLayer.context.globalAlpha = 1;
        activeLayer.context.globalCompositeOperation = "source-over";
        activeLayer.context.drawImage($('#working_canvas')[0], 0, 0);
    },
    
    prepare: function()
    {
        workingContext.clearRect(0, 0, canvasWidth, canvasHeight);
        workingContext.globalCompositeOperation = "copy";
    },
    
    undo: function()
    {
        workingContext.clearRect(0, 0, canvasWidth, canvasHeight);
        disable_undo()
    }
};

eraserTool = {
    imgSrc: "eraser.png",
    hidesWorkingCanvas: true,
    
    draw: function(event)
    {
        var x = getX(event);
        var y = getY(event);
        
        lineWidth();
        lines(lastX, lastY, x, y, activeLayer.context);
        
        lastX = x
        lastY = y
        
        enable_undo()
    },
    
    commit: function()
    {
    },
    
    prepare: function()
    {
        workingContext.globalAlpha = 1;
        workingContext.globalCompositeOperation = "copy";
        workingContext.drawImage(activeLayer.canvas[0], 0, 0);
        
        
        activeLayer.context.globalCompositeOperation="destination-out"
    },
    
    undo: function()
    {
        activeLayer.context.globalAlpha = 1;
        activeLayer.context.globalCompositeOperation = "copy";
        activeLayer.context.drawImage($('#working_canvas')[0], 0, 0);
        disable_undo()
    }
};

clearTool = {
    imgSrc: "eraser.png",
    hidesWorkingCanvas: true,
    
    draw: function()
    {
        activeLayer.context.clearRect(0, 0, canvasWidth, canvasHeight)
        
        enable_undo()
    },
    
    commit: function()
    {
    },
    
    prepare: function()
    {
        workingContext.globalAlpha = 1;
        workingContext.globalCompositeOperation = "copy";
        workingContext.drawImage(activeLayer.canvas[0], 0, 0);
        
        
        activeLayer.context.globalCompositeOperation="destination-out"
    },
    
    undo: function()
    {
        activeLayer.context.globalAlpha = 1;
        activeLayer.context.globalCompositeOperation = "copy";
        activeLayer.context.drawImage($('#working_canvas')[0], 0, 0);
        disable_undo()
    }
};

tool = nextTool = penTool;

function commit(next)
{
    tool.commit();
    tool = next;
    activeLayer = nextLayer;
    tool.prepare();
    updateLayers();
}

function startDrawing(event)
{
    var x = getX(event);
    var y = getY(event);
    
    //dump(event)
    
    //alert("x,y: " + x + "," + y )
    if (event.metaKey || event.ctrlKey)
    {
        $("#center_x").val(x);
        $("#center_y").val(y);
    }
    else if (event.altKey)
    {
        eyeDropper(x,y);
    }
    else
    {
        commit(nextTool);
        
        if (!event.shiftKey)
        {
            lastX = x;
            lastY = y;
        }
        
        startColor = [$("#hue").val(), $("#sat").val(), $("#lit").val(), $("#alpha").val()]
        startSpeed = [$("#hue_speed").val(), $("#sat_speed").val(), $("#lit_speed").val(), $("#alpha_speed").val()]
        
        tool.draw(event);
        $(document).bind("mousemove.tools", draw);
        $(document).bind("mouseup.tools", stopDrawing);
    }
    drawGuides();
    return false
}

function draw(event)
{
    if (getX(event) != lastX || getY(event) != lastY)
    {
        tool.draw(event);
    }
    return false
}

function stopDrawing(event)
{
    tool.draw(event)
    $(document).unbind(".tools");
    updateLayers();
    if ($("#reset:checked").length)
    {
        setColor(startColor[0], startColor[1], startColor[2])
        $("#alpha").val(startColor[3])
        setColorSpeed(startSpeed[0], startSpeed[1], startSpeed[2])
        $("#alpha_speed").val(startSpeed[3])
    }
    return false
}