var i, style;
var STYLES = ["sketchy", "shaded", "chrome", "fur", "longfur", "web", "", "drunk_master", "squares", "ribbon", "koch", "", "circles", "grid"];
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;

var menu, selector, option;

var canvas;
var context;
var hist = null;
var mouseX = 0;
var mouseY = 0;

var isMenuMouseOver = false;
var isMouseDown = false;

function el(the_id) 
{
    return document.getElementById(the_id);
}

init();

function init() 
{
    //menu = el("menu");
    //menu.style.left = ((SCREEN_WIDTH - menu.offsetWidth) / 2) + "px";
    //menu.style.visibility = "visible";
    //menu.addEventListener("mouseover", onMenuMouseOver, false);
    //menu.addEventListener("mouseout", onMenuMouseOut, false);
    
    canvas = el("the-canvas"); //document.createElement("canvas");
    canvas.width = SCREEN_WIDTH;
    canvas.height = SCREEN_HEIGHT;
    canvas.style.cursor = "crosshair";
    context = canvas.getContext("2d");
    context.fillStyle = "rgb(255, 255, 255)";
    context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    el("save").addEventListener("click", save, false);
    el("clear").addEventListener("click", clear, false);
    
    el("the-opacity").addEventListener("change", onOpacityChange, false);
    el("the-line-width").addEventListener("change", onLineWidthChange, false);
    el("the-composite-op").addEventListener("change", onCompositeOpChange, false);
    
    el("the-undo").addEventListener("click", onUndo, false);
    el("the-redo").addEventListener("click", onRedo, false);
    
    el("the-color").addEventListener("change", onColorChange, false);
    
    hist = new History( getCurrentImg() );

    selector = el("selector");
    selector.addEventListener("change", onSelectorChange, false);
    
    for (i = 0; i < STYLES.length; i++) 
    {
        option = document.createElement("option");
        option.id = i;
        option.innerHTML = STYLES[i].toUpperCase();
        selector.appendChild(option);
    }

    if (window.location.hash) 
    {
        var hash = window.location.hash.substr(1, window.location.hash.length);

        for (i = 0; i < STYLES.length; i++) 
        {
            if (hash == STYLES[i]) 
            {
                style = eval("new " + STYLES[i] + "(context)");
                selector.selectedIndex = i; 
                break;
            }
        }
    }

    if (!style)
    {
        style = eval("new " + STYLES[0] + "(context)")
    }

    //document.onmousedown = onDocumentMouseDown;
    //document.onmouseout = onCanvasMouseUp;
    //canvas.onmouseout   = onCanvasMouseUp;
    //canvas.onmouseover  = onCanvasMouseDown;
    canvas.onmouseup    = onCanvasMouseUp;
    canvas.onmousedown  = onCanvasMouseDown;
    canvas.onmousemove  = onCanvasMouseMove;
    canvas.ontouchstart = onCanvasTouchStart;
    canvas.ontouchend   = onCanvasTouchEnd;
    canvas.ontouchmove  = onCanvasTouchMove

    document.onkeydown  = onKey;
}

function onDocumentMouseDown(a) 
{
    return isMenuMouseOver
}

function onSelectorChange(e) 
{
    if (STYLES[selector.selectedIndex] == "") 
    {
        return;
    }

    style.destroy();
    style = eval("new " + STYLES[selector.selectedIndex] + "(context)");
    
    window.location.hash = STYLES[selector.selectedIndex]
}

function update_undo_redo()
{
    if( hist )
    {
        el("the-undo").disabled = !hist.can_undo();
        el("the-redo").disabled = !hist.can_redo();
    }
}

function reinit_style()
{
    if( style )
    {
        style.init( context );
        //style.destroy();
        //style = eval("new " + STYLES[selector.selectedIndex] + "(context)");
    }
}

function pageX(elem) 
{
       return elem.offsetParent ?
               elem.offsetLeft + pageX( elem.offsetParent ) :
               elem.offsetLeft;
}

// Определение координаты элемента по вертикали
function pageY(elem) 
{
       return elem.offsetParent ?
               elem.offsetTop + pageY( elem.offsetParent ) :
               elem.offsetTop;
}

function onOpacityChange(e) 
{
    curr_opacity = el("the-opacity").value;
    reinit_style();
}

function onLineWidthChange(e) 
{
    curr_line_width = el("the-line-width").value;
    reinit_style();
}

function onCompositeOpChange(e)
{   
    curr_composite_op = el("the-composite-op").value;
    reinit_style();
}

function onMenuMouseOver(a) 
{
    isMenuMouseOver = true
}

function onMenuMouseOut(a) 
{
    isMenuMouseOver = false
}

function ondocumentMouseDown(a) 
{
    return !isMenuMouseOver
}

function onCanvasMouseDown(a) 
{
    isMouseDown = true;
    style.strokeStart(mouseX, mouseY)
}

function onCanvasMouseUp(a) 
{
    isMouseDown = false;
    style.strokeEnd(mouseX, mouseY)
    
    saveCurrent();
    update_undo_redo();
}

function onCanvasMouseMove(a) 
{
    if (!a) 
    {
        a = window.event
    }

    //mouseX = a.offsetX + (a.clientX - a.x); //a.clientX;
    //mouseY = a.offsetY + (a.clientY - a.y); //a.clientY;
    mouseX = (a.pageX - pageX(a.target));
    mouseY = (a.pageY - pageY(a.target));

    if (!isMouseDown) { return }

    style.stroke(mouseX, mouseY)
}

function onCanvasTouchStart(a) 
{
    if (a.touches.length == 1) 
    {
        var b = a.touches[0];
        //var x = b.offsetX + (b.clientX - b.x);
        //var y = b.offsetY + (b.clientY - b.y);
        var x = (b.pageX - pageX(b.target));
        var y = (b.pageY - pageY(b.target));
        style.strokeStart(x, y);
    }

    return false
}

function onCanvasTouchEnd(a) 
{
    if (a.touches.length == 1) 
    {
        var b = a.touches[0];
        //var x = b.offsetX + (b.clientX - b.x);
        //var y = b.offsetY + (b.clientY - b.y);
        var x = (b.pageX - pageX(b.target));
        var y = (b.pageY - pageY(b.target));v
        style.strokeEnd(x, y)
        
        saveCurrent();
        update_undo_redo();
    }
}

function onCanvasTouchMove(a) 
{
    if (a.touches.length == 1) 
    {
        var b = a.touches[0];
        //var x = b.offsetX + (b.clientX - b.x);
        //var y = b.offsetY + (b.clientY - b.y);
        var x = (b.pageX - pageX(b.target));
        var y = (b.pageY - pageY(b.target));
        style.stroke(x, y)
    }
}

function onKey(a) 
{
    if (!a) var a = window.event;

    if (a.ctrlKey || a.shiftKey) 
    {
        if (a.keyCode == 90) // Z 
        {
            onUndo();
            return true;
        }
        else if (a.keyCode == 89) // Y 
        {
            onRedo();
            return true;
        }
        else if( a.keyCode == 83 ) // S
        {
            save();
            return true;
        }
    }

    return false;
}

function onUndo() 
{
    if( hist.undo() )
    {
        applyCurrent();
        update_undo_redo();
        reinit_style();
    }
    
    update_undo_redo();
}

function onRedo() 
{
    if( hist.redo() )
    {
        applyCurrent();
        update_undo_redo();
        reinit_style();
    }
}

function getCurrentImg()
{
    return context.getImageData(0, 0, canvas.width, canvas.height);
}

function saveCurrent()
{
    hist.save( getCurrentImg() );
}

function applyCurrent()
{
    context.putImageData( hist.curr(), 0, 0 );
}

function onColorChange()
{
    var o = el("the-color");
    curr_color_r = Math.round(this.color.rgb[0]*255);
    curr_color_g = Math.round(this.color.rgb[1]*255);
    curr_color_b = Math.round(this.color.rgb[2]*255);
    reinit_style();
}



function save() 
{
    window.open(canvas.toDataURL("image/png"), "mywindow");
}

function clear() 
{
    var answer = confirm("Clear your picture?");
    if (answer) 
    {
        context.globalCompositeOperation = "source-over";
        context.fillStyle = "rgb(255, 255, 255)";
        context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
        style = eval("new " + STYLES[selector.selectedIndex] + "(context)");
        points = new Array();
        count = 0;
    }
};
