function dump(obj)
{
    msg = ""
    for (p in obj)
    {
        msg = msg + p + ": " + obj[p] + '\n'
    }
    alert(msg)
}

var canvas_offset_x
var canvas_offset_y

var id_counter = 0
function unique_id(prefix)
{
    id_counter += 1;
    return prefix + "-id-" + id_counter
}

function lineWidth(w)
{
    if (w)
    {
        $("#line_width").val(w);
    }
    else
    {
        w = Number($("#line_width").val());
    }
    workingContext.lineWidth = w;
    activeLayer.context.lineWidth = w;
}

function flattenVisible()
{
    var context = $('#flatten_canvas')[0].getContext("2d");
    context.clearRect(0, 0, canvasWidth, canvasHeight);
    
    for (var i = layers.length - 1; i >= 0; i--)
    {
        if (!layers[i].hidden)
        {
            context.drawImage(layers[i].canvas[0], 0, 0);
            if (layers[i] == activeLayer && !tool.hidesWorkingCanvas)
            {
                context.drawImage($("#working_canvas")[0], 0, 0);
            }
        }
    }
}

function save()
{
    flattenVisible();
    $("#save_img").attr("src", $('#flatten_canvas')[0].toDataURL()); 
    $("#save").css("display", "block");
}

function eyeDropper(x, y)
{
    flattenVisible();
    var context = $('#flatten_canvas')[0].getContext("2d");
    var rgba = context.getImageData(x,y,1,1).data
    
    if (rgba[3] == 0)
    {
        hsl = [0,0,100]
    }
    else
    {
        hsl = RGBtoHSL(rgba)
    }
    setColor(hsl[0], hsl[1], hsl[2])
}

function drawGuide(x, y, theta)
{
    var len = canvasHeight + canvasWidth;
    guideContext.strokeWidth = 2;
    guideContext.strokeStyle = "gray"
    
    guideContext.beginPath();
    guideContext.moveTo(x, y);
    guideContext.lineTo(x - len*Math.sin(theta), y + len*Math.cos(theta));
    guideContext.stroke();
}

function drawGuides()
{
    var x = Number($("#center_x").val());
    var y = Number($("#center_y").val());
    var n = Number($("#rotate").val());
    var m = $("#mirror:checked").length;
    
    if (m)
    {
        n *= 2
    }
    
    guideContext.clearRect(0, 0, canvasWidth, canvasHeight);
    
    if ($("#guides:checked").length)
    {
        for (var i = 0; i < n; i++)
        {
            var theta = i * 2 * Math.PI / n;
            drawGuide(x, y, theta);
        }
    }
}

function setup()
{
    var workingCanvas = $("#working_canvas");
    workingContext = workingCanvas[0].getContext("2d");
    
    var guideCanvas = $("#guide_canvas");
    guideContext = guideCanvas[0].getContext("2d");
    
    canvasWidth = guideCanvas.width()
    canvasHeight = guideCanvas.height()
    
    canvas_offset_x = guideCanvas.offset().left
    canvas_offset_y = guideCanvas.offset().top
    
    new Layer();
    $("#layers").sortable({handle: "canvas", change: function(event, ui) {
        var activeId = ui.item.attr("id")
        var layerOrder = $("#layers").sortable('toArray')
        layers = [];
        
                                                            var layerLinks = $("#layers > li:not(.ui-sortable-helper) a.delete");
        
        for (var i = 0; i < layerOrder.length; i++)
        {
            var currentId = layerOrder[i]
            if (currentId == activeId)
            {
                continue
            }
            else if (currentId == "")
            {
                currentId = activeId
            }
            
            layerLink = $("#" + currentId + " a.delete")
            layers.push($(layerLink).data("layer"));
        }
        updateLayers();
    },
    helper: function(event, ui)
    {
        var li = $(event.target).parents("li")
        var canvas = li.find("canvas")[0];
        var active = Boolean(li.find("input.active:checked").length)
        var visible = Boolean(li.find("input.visible:checked").length)
        
        var helper = $(layerControlHtml);
        helper.find("canvas")[0].getContext("2d").drawImage(canvas,0,0);
        
        if (active)
        {
            helper.find("input.active").attr("name", "helper_active").attr("checked", "checked");
        }
        if (!visible)
        {
            helper.find("input.visible").removeAttr("checked");
        }
        return helper;
    }});
    
    guideCanvas.mousedown(startDrawing);
    
    //window.onmouseup = stopDrawing;
    //window.onmouseover = resumeDrawing;
    
    lineWidth(2);
    workingContext.lineCap = "round";
    
    updateColorPreview();
    
    tool = nextTool = penTool;
    
    createColorLink(300, 100, 50);
    createColorLink(0, 100, 50);
    createColorLink(60, 100, 50);
    createColorLink(120, 100, 50);
    createColorLink(180, 100, 50);
    createColorLink(240, 100, 50);
    createColorLink(0, 0, 0);
    createColorLink(0, 0, 100);
    
    $("#hue_controls").attr("MaxValue", 360);
    $("#sat_controls").attr("MaxValue", 100);
    $("#lit_controls").attr("MaxValue", 100);
    $("#alpha_controls").attr("MaxValue", 100);
    
    $("#width_controls a").click(function () {
        lineWidth(Number($(this).text()));
        return false;
    });
    
    $("#line_width").change(function() {
        lineWidth(Number($(this).val()));
    })
    
    $("#color_controls .value").change(function (){
        updateColorPreview();
    });
    
    $("#rainbow").click(function () {
        setColorSpeed(2, 0, 0);
        return false
    });
    
    $("#solid").click(function () {
        setColorSpeed(0, 0, 0);
        return false
    });
    
    $("input[name='tool']").change(function() {
        toolName = $(this).val();
        if (toolName == "pen")
        {
            nextTool = penTool;
        }
        else if (toolName == "eraser")
        {
            nextTool = eraserTool
        }
    })
    
    $("#color_preview").click(function() {
        saveColor();
    });
    
    $("#fill").click(function() {
        commit(fillTool);
        tool.draw();
        updateLayers();
        return false;
    });
    
    $("#clear").click(function() {
        commit(clearTool);
        tool.draw();
        updateLayers();
        return false;
    });
    
    $("#undo").click(function() {
        tool.undo();
        updateLayers();
        return false;
    });
    
    $("#save_link a").click(function() {
        save();
        return false;
    });
    
    $(".guides").change(function() {
        drawGuides();
    })
    
    $("#new_layer").click(function() {
        new Layer();
        $("#layers").sortable("refresh");
        return false;
    })
    
    drawGuides();
    
    //Hide unsupported features
    if (!workingCanvas[0].toDataURL)
    {
        $("#save_link").hide();
    }
    
    if (!workingContext.getImageData)
    {
        $("#eyedropper").hide();
    }
}

$(setup)