var language = window.navigator.userLanguage || window.navigator.language;
language = language.split('-',1)[0];

function loadjs(filename, id, callback) {
    var done = false;
    var script = document.createElement( 'script');
    
    script.type = 'text/javascript';
    script.onload = handleLoad;
    script.onreadystatechange = handleReadyStateChange;
    script.onerror = handleError;
    script.src = filename;

    if (id != '') {
        script.id = id;
    }
    
    document.head.appendChild(script);

    function handleLoad() {
        if (!done) {
            done = true
            if (callback) {
                callback(filename, "ok");
            }
        }
    }

    function handleReadyStateChange() {
        var state;

        if (!done) {
            state = script.readyState;
            if (state === "complete") {
                handleLoad();
            }
        }
    }
    function handleError() {
        if (!done) {
            done = true;
            if (callback) {
                callback(filename, "error");
            }
        }
    }
}


for (i = 0; i < 24; i++){
    window['pack'+i+'A'] = false;
}

var x;
var imagepackN = 0;
var fakeNeighS;
var fakeNeighD;
var swipe = true;
var newHigh = false;
var cx;
var cy;

//~ for (var k = 0; k < 24; k++){
    //~ window['img'+k] = new Image();
    //~ window['img'+k].src = 'images/pack'+k+'/pixel.jpg';
    //~ window['img'+k].onload = (function(nr) {
        //~ return function() {
            //~ window['pack'+nr+'A'] = true;
            //~ imagepackN += 1;
        //~ }
    //~ }(k));
//~ }

//
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
var version = '1.2.8';
var available_version;
var NUM = 3;
var imageW;
var imageH;
var kepW;
var kepH;
var ratio;
var SIZEX;
var SIZEY;
var scaledW;
var swaps;
var lost = false;
var hintMovePenalty = 5;
var hintTimePenalty = 10;
var fullImageMovePenalty = 10;
var fullImageTimePenalty = 15;
var imagecount = 23;
var i;
var src = -1;
var dst = -1;
var place = new Array();
var buttons = new Array("back","timer","animation","grid","hint","swap","showfull");
var sourceRect;
var destinationRect;
var sourceImage;
var destinationImage;
var imageStroke;
var animation = true;
var grid = true;
var animoldicon;
var animold; 
var moves;
var animv;
var swapped = false;
var hint = false;
var once = false;
var swapHint = false;
var getScore;
var setScore;
var customGame = false;

// keverés
function keveres() {
    for (i in place) {
        var r = Math.floor(Math.random() * place.length);
        var temp = place[i];
        place[i] = place[r];
        place[r] = temp;
        if (isEnd()) {
            keveres();
        }
    }
}

function getXYD(n) {
    var x = (n % NUM) * SIZEX;
    var y = Math.floor(n / NUM) * SIZEY;
    return {'x': x, 'y': y};
}

function getXYS(n) {
    var x = (n % NUM) * imageW;
    var y = Math.floor(n / NUM) * imageH;
    return {'x': x, 'y': y};
}

function getN(x, y) {
    return Math.floor(y / SIZEY) * NUM + Math.floor(x / SIZEX); 
}

function is_int(value){ 
  if((parseFloat(value) == parseInt(value)) && !isNaN(value)){
      return true;
  } else { 
      return false;
  } 
}

function scoreCallback() {  
    return {
        'hours': setScore[0],
        'minutes': setScore[1],
        'seconds': setScore[2],
        'moves': setScore[3]
    }; 
}

function isWon() {
    if (cWon == true) {
        getScore = scoreCallback();
        return true;
    }
    return false;
}

function scores() {
    if (customGame) {
        return;
    }
    setScore = [];
    setScore[0] = hours;
    setScore[1] = minutes;
    setScore[2] = seconds;
    setScore[3] = moves;
    var highMoves = localStorage.getItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves');
    var highTime = localStorage.getItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time');
    if (highTime) {
        var highHour = highTime.split(':')[0];
        var highMin = highTime.split(':')[1];
        var highSec = highTime.split(':')[2];
    }
    var timeSum = (hours*60*60)+(minutes*60)+seconds;
    var highTimeSum = (highHour*60*60)+(highMin*60)+highSec;
    if (!highMoves || gamemode == 'classic' && highMoves > moves) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
    if (!highMoves || gamemode == 'classic' && highMoves == moves && highTimeSum > timeSum) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
    if (!highTime || gamemode == 'challenge' && highTimeSum < timeSum) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
    if (!highTime || gamemode == 'challenge' && highTimeSum == timeSum && highMoves > moves) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
    if (!highMoves || gamemode == 'fun' && highMoves > moves) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
    if (!highMoves || gamemode == 'fun' && highMoves == moves && highTimeSum > timeSum) {
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_moves', moves);
        localStorage.setItem(packN+'_'+selectedImage+'_'+NUM+'_'+gamemode+'_time', hours+':'+minutes+':'+seconds);
        newHigh = true;
        return;
    }
}

function szomszedok(src, dst) {
    if (swapHint) {
        return true;
    }
    
    if (swipe) {
        //egymás alatt
        if ((dst - src) % NUM == 0) {
            fakeNeighS = src;
            if (src < dst) {
                fakeNeighD = src + NUM;
            } else {
                fakeNeighD = src - NUM;
            }
            return true;
        }
        //egymás mellett
        var balra = src % NUM;
        var jobbra = NUM - (balra + 1);
        
        if (src > dst) {
            if (src - dst <= balra) {
                fakeNeighS = src;
                fakeNeighD = src - 1;
            }
            return true;
        } else {
            if (dst - src <= jobbra) {
                fakeNeighS = src;
                fakeNeighD = src + 1;
            }
            return true;
        }
    }
    
    var s = Math.min(src, dst);
    var d = Math.max(src, dst);
    
    // egymás alatt vannak
    if (s + NUM == d) {
        return true;
    }
    // egymás mellett vannak, de nem új sorban
    if ( (s % NUM + 1 == d % NUM ) && (d - s != NUM + 1) && (d - s < 6) ) {
        return true;
    }
    
    return false;
}

function isEnd() {
    for (i in place) {
        if (place[i] != i) {
            return false;
        }
    }
    return true;
}

function drawHint() {
    for (i in place) {    
        i = parseInt(i);
        /*if (i == 0) { // első
            var szele = place.indexOf(parseInt(i));
            ctx.fillRect(getXYD(szele).x,getXYD(szele).y,SIZEX,SIZEY);
        }*/
        if (i < NUM) { //felső
            var szele = place.indexOf(i);
            //~ var lingrad = ctx.createLinearGradient(0, getXYD(szele).y, 0, getXYD(szele).y+SIZEY);
            //~ lingrad.addColorStop(0, 'rgba(255,255,0,1)');
            //~ lingrad.addColorStop(0.05, 'rgba(255,255,0,0)');
            //~ ctx.fillStyle = lingrad;
            ctx.fillStyle = '#ffff00';
            ctx.fillRect(getXYD(szele).x,getXYD(szele).y,SIZEX,SIZEY*0.05);
        }
        if ((i+1) % NUM == 0) { //jobb
            var szele = place.indexOf(i);
            //~ var lingrad = ctx.createLinearGradient(getXYD(szele).x+SIZEX, 0, getXYD(szele).x, 0);
            //~ lingrad.addColorStop(0, 'rgba(0,255,0,1)');
            //~ lingrad.addColorStop(0.05, 'rgba(0,255,0,0)');
            //~ ctx.fillStyle = lingrad;
            ctx.fillStyle = '#00ff00';
            ctx.fillRect(getXYD(szele).x+SIZEX*0.95,getXYD(szele).y,SIZEX*0.05,SIZEY);
        }
        if ((i % NUM) == 0) { //bal
            var szele = place.indexOf(i);
            //~ var lingrad = ctx.createLinearGradient(getXYD(szele).x, 0, getXYD(szele).x+SIZEX, 0);
            //~ lingrad.addColorStop(0, 'rgba(0,0,255,1)');
            //~ lingrad.addColorStop(0.05, 'rgba(0,0,255,0)');
            //~ ctx.fillStyle = lingrad;
            ctx.fillStyle = '#0000ff';
            ctx.fillRect(getXYD(szele).x,getXYD(szele).y,SIZEX*0.05,SIZEY);
        }
        if ((NUM * (NUM-1)) < i+1) { //alsó
            var szele = place.indexOf(i);
            //~ var lingrad = ctx.createLinearGradient(0, getXYD(szele).y+SIZEY, 0, getXYD(szele).y);
            //~ lingrad.addColorStop(0, 'rgba(255,0,0,1)');
            //~ lingrad.addColorStop(0.05, 'rgba(255,0,0,0)');
            //~ ctx.fillStyle = lingrad;
            ctx.fillStyle = '#ff0000';
            ctx.fillRect(getXYD(szele).x,getXYD(szele).y+SIZEY*0.95,SIZEX,SIZEY*0.05);
        }
    }
}

function repaint2() {
        object0 = new Menu();
        for (i in place) {    
            object0.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
        }
        object0.draw();
        
        if (hint == true) {
            drawHint();
        }
        
        if (grid == true && !videopuzzle) {
            imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
            imageStroke.draw();
        }
}

function repaint() {
    if (animation == false || alertM == true) {
        ctx.clearRect(0, 0, scaledW, HEIGHT);
        object = new Menu();
        for (i in place) {    
            object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
        }
        object.draw();
        
        if (hint == true) {
            drawHint();
        }
        
        if (grid == true && !videopuzzle) {
            imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
            imageStroke.draw();
        }
        showfullIcon = imageOff;
    }
    
    object = new Menu();
    if (!Config.simpleMode) {
        ctx.clearRect(WIDTH-WIDTH*0.15, HEIGHT*0.07, WIDTH*0.15, HEIGHT*0.08);
        object.add(new MyTextItem('movesn', moves, WIDTH-10, HEIGHT*0.1, HEIGHT*0.05, 0 ,'right'));
        object.draw();
    }
    // animation >
    if (animation == true) {
        if (destinationImage) {
            sourceRect.draw();
            destinationRect.draw();
            destinationImage.draw();
        }
        
        if (sourceImage) {
            sourceImage.draw();
        }
    } 
    // <
    if (mode == 'classic') {
        animIcon = animoldicon;
    }
            
    if (isEnd() && !videopuzzle) {
        ctx.drawImage(kep, 0, 0, scaledW, HEIGHT);
    }
    if (!Config.simpleMode) {
        if (!timerStarted) {
            var timerDraw = new MyTextItem('timer', minutes+':'+seconds, WIDTH-10, HEIGHT*0.04, HEIGHT*0.05, 0 ,'right');
            timerDraw.draw();
        }
    }
}

function buttonRepaint() {
    if (!Config.simpleMode) {
        object2 = new Menu();
        //ctx.clearRect(WIDTH*0.85, HEIGHT*0.15, WIDTH*0.15, HEIGHT*0.9);
        object2.add(new ImageMenuItem('hint', 'images/hint_'+hintIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.20-BSIZE/2, BSIZE, BSIZE, 0));
        object2.add(new ImageMenuItem('timer', '', WIDTH*0.9, 0, WIDTH*0.1, HEIGHT*0.1, 0));
        if (mode == 'classic') {
            object2.add(new ImageMenuItem('swap', 'images/swap_'+swapIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.35-BSIZE/2, BSIZE, BSIZE, 0, 0, swaps));
        } else {
            object2.add(new ImageMenuItem('swap', 'images/swap_'+swapIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.35-BSIZE/2, BSIZE, BSIZE, 0));
        }
        object2.add(new ImageMenuItem('showfull', 'images/full_'+showfullIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.50-BSIZE/2, BSIZE, BSIZE, 0));
        object2.add(new ImageMenuItem('grid', 'images/grid_'+gridIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.65-BSIZE/2, BSIZE, BSIZE, 0));
        //object2.add(new ImageMenuItem('animation', 'images/anim_'+animIcon+'.png', WIDTH-BSIZE*1.2, HEIGHT*0.80-BSIZE/2, BSIZE, BSIZE, 0));
        if (Config.quickMode == "0") {
            object2.add(new ImageMenuItem('back', 'images/back_'+imageOn+'.png', WIDTH-BSIZE*1.2, HEIGHT-BSIZE*1.2, BSIZE, BSIZE, 0));
        }
        object2.draw();
    }
}

function startPuzzle(mode) {
    cWon = false;
    newHigh = false;
    if (Config.quickMode != 0) {
        if (videopuzzle) {
            video.addEventListener("canplay", function() {
                animation = false;
                $('#video').get(0).play();
            });
        }
    } else {
        if (videopuzzle) {
            animation = false;
            $('#video').get(0).play();
        }
    }
    this.mode = mode;
    if (mode == 'challenge') {
        gamemode = 'challenge';
        if (NUM == 2) {
            msecs=100;
            seconds=2;
            minutes=0;
        }
        if (NUM == 3) {
            msecs=100;
            seconds=15;
            minutes=0;
        }
        if (NUM == 4) {
            msecs=100;
            seconds=35;
            minutes=0;
        }
        if (NUM == 5) {
            msecs=100;
            seconds=20;
            minutes=1;
        }
        if (NUM == 6) {
            msecs=100;
            seconds=40;
            minutes=2;
        }
        if (NUM == 7) {
            msecs=100;
            seconds=40;
            minutes=4;
        }
        if (NUM == 8) {
            msecs=100;
            seconds=30;
            minutes=7;
        }
        if (NUM == 9) {
            msecs=100;
            seconds=30;
            minutes=9;
        }
    }
    if (mode == 'classic') {
        gamemode = 'classic';
        swaps = NUM-2;
    }
    if (mode == 'fun') {
        gamemode = 'fun';
        swaps = 1;
    }
    maxW = WIDTH*0.8;
    if (Config.simpleMode) {
        maxW = WIDTH;
    }
    animoldicon = animIcon;
    animold = animation;
    moves = 0;
    ctx.clearRect(0, 0, WIDTH, HEIGHT);
    destinationImage = null;
    sourceImage = null;
    // feltöltés
    src = -1;
    dst = -1;
    place = new Array();
    for (i = 0; i < NUM * NUM; i++) {
        place[i] = i;
    }
    
    keveres();

    if (Config.quickMode != 0) {
        if (videopuzzle) {
            video.addEventListener("canplay", function() {
                imageW = video.videoWidth / NUM;
                imageH = video.videoHeight / NUM;
                kepW = Math.max(video.videoWidth, video.videoHeight);
                kepH = Math.min(video.videoWidth, video.videoHeight);
                ratio = kepW / kepH;
                scaledW = HEIGHT * ratio;
                
                if (Config.simpleMode) {
                    scaledW = maxW;
                }
                if (maxW < scaledW) {
                    scaledW = maxW;
                }
                
                SIZEX = scaledW / NUM;
                SIZEY = HEIGHT / NUM;
            });
        }
        if (!videopuzzle) {
            kep.onload = function() {
                imageW = kep.width / NUM;
                imageH = kep.height / NUM;
                kepW = Math.max(kep.width, kep.height);
                kepH = Math.min(kep.width, kep.height);
                ratio = kepW / kepH;
                scaledW = HEIGHT * ratio;
                
                if (Config.simpleMode) {
                    scaledW = maxW;
                }
                if (maxW < scaledW) {
                    scaledW = maxW;
                }
                
                SIZEX = scaledW / NUM;
                SIZEY = HEIGHT / NUM;

                //console.log('x: ' + SIZEX, ' y: ' + SIZEY, ' n: ' + NUM, ' w: ' + imageW, ' h: ' + imageH)
            
                if (animation == true) {
                    object = new Menu();
                    for (i in place) {    
                        object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
                    }
                    object.draw();
                    
                    if (hint == true) {
                        drawHint();
                    }
                    
                    if (grid == true && !videopuzzle) {
                        imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
                        imageStroke.draw();
                    }
                }
            }
        }
    } else {
        if (videopuzzle) {
            imageW = video.videoWidth / NUM;
            imageH = video.videoHeight / NUM;
            kepW = Math.max(video.videoWidth, video.videoHeight);
            kepH = Math.min(video.videoWidth, video.videoHeight);
        }
        if (!videopuzzle) {
            imageW = kep.width / NUM;
            imageH = kep.height / NUM;
            kepW = Math.max(kep.width, kep.height);
            kepH = Math.min(kep.width, kep.height);
        }
        ratio = kepW / kepH;
        scaledW = HEIGHT * ratio;
        
        if (Config.simpleMode) {
            scaledW = maxW;
        }
        if (maxW < scaledW) {
            scaledW = maxW;
        }
        
        SIZEX = scaledW / NUM;
        SIZEY = HEIGHT / NUM;

        //console.log('x: ' + SIZEX, ' y: ' + SIZEY, ' n: ' + NUM, ' w: ' + imageW, ' h: ' + imageH)
            
        if (animation == true) {
            object = new Menu();
            for (i in place) {    
                object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
            }
            object.draw();
            
            if (hint == true) {
                drawHint();
            }
            
            if (grid == true && !videopuzzle) {
                imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
                imageStroke.draw();
            }
        }
    }
    
    if (Config.quickMode != 0) {
        if (videopuzzle) {
        video.addEventListener("canplay", function() {
            repaint();
            buttonRepaint();
        });
        } else {
            repaint();
            buttonRepaint();
        }
    } else {
        if (videopuzzle) {
            repaint();
            buttonRepaint();
        } else {
            repaint();
            buttonRepaint();
        }
    }
    $('canvas').bind('click', function(event){
        if (activePage != 'game'){
            return;
        }

        //button clickChecks
        for (i in buttons) {
            if(clickCheck(event, buttons[i])) {
                return false;
            }
        }
    });
}

$('canvas').bind('click', function(event){
    if (activePage != 'game'){
        return;
    }

    //button clickChecks
    for (i in buttons) {
        if(clickCheck(event, buttons[i])) {
            return false;
        }
    }
});

var mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|Mobile|XiaoMi/i.test(navigator.userAgent);
var eventdown = mobile ? "touchstart" : "mousedown";
var eventup = mobile ? "touchend" : "mouseup";

canvas.addEventListener(eventdown, function(event) {
    //~ var event = event.originalEvent;
    if (swipe && !swapHint) {
        if (activePage != 'game'){
            return;
        }
        // a játék vége után már ne kattintgasson
        if (mobile) {
            for (var i in event.touches) {
                var check = event.touches[i].clientX;
                if (check) {
                    var touch = event.touches[i];
                    cx = touch.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
                    cy = touch.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
                }
            }
        } else {
            cx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
            cy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
        }
        
        if (alertM == 1) {
            repaint();
            buttonRepaint() 
            alertM = 0;
            if (!timerStarted && !isEnd()) {
                myTimer('start');
            }
            if (videopuzzle) {
                clearTimeout(videoendloop);
            }
            return false;
        }

        if (lost) {
            return false;
        }
        
        if (isEnd()) {
            //~ myTimer('stop');
            //~ videopuzzle = false;
            //~ if (Config.quickMode != 0) {
                //~ firstImage();
            //~ }
            return false;
        }

        //képen kívüli rész
        if (cx > scaledW) {
            return false;
        }
        // nincs forrás kiválasztva
        if (src == -1) {
            //if (mode != 'challenge') {
                if (!timerStarted) {
                    myTimer("start");
                }
            //}
            src = getN(cx, cy);
            ctx.fillStyle = 'rgba('+Config.color+',0.5)';
            ctx.strokeStyle = 'rgba('+Config.color+',0.5)';
            ctx.lineWidth = SIZEX*0.02;
            if (!videopuzzle) {
                ctx.strokeStyle = 'rgba('+Config.color+',0.5)';
                ctx.fillRect(getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
            }
            //ctx.strokeRect(getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
            if (mode == 'classic' && swapped) {
                animation = animold;
                swapped = false;
            }
            return false;
        }

        // ha van forrás kiválasztva
        if (src >= 0) {
            dst = getN(cx, cy);
            // ha forrás = cél, akkor kijelölés megszüntetése
            if (src == dst || src != dst) {
                repaint();
                if (animation) {
                    object = new Menu();
                    for (i in place) {    
                        object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
                    }
                    object.draw();
                    if (hint == true) {
                        drawHint();
                    }
                    if (grid == true && !videopuzzle) {
                        imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
                        imageStroke.draw();
                    }
                }
                src = -1;
                dst = -1;
                fakeNeighS = -1;
                fakeNeighD = -1;
                return false;
            }
            
            // ha szomszédok, akkor csere
            if (szomszedok(src, dst)) {
                if (mode == 'classic') {
                    if (swapHint) {
                        swaps-=1;
                        swapHint=false;
                        swapIcon=imageOff;
                        swapped = true;
                    }
                }
                if (mode != "fun") {
                    hint = false;
                    hintIcon = imageOff;
                    buttonRepaint();
                }
                // animation >
                if (animation == true) {
                    sourceRect = new MyRectItem('sourcerect', getXYD(src).x, getXYD(src).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    destinationRect = new MyRectItem('destinationrect', getXYD(dst).x, getXYD(dst).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    sourceImage = new MyImageItem('source',kep, getXYS(place[src]).x, getXYS(place[src]).y, imageW, imageH, getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
                    destinationImage = new MyImageItem('destination',kep, getXYS(place[dst]).x, getXYS(place[dst]).y, imageW, imageH, getXYD(dst).x, getXYD(dst).y, SIZEX, SIZEY);
                    move(sourceImage, getXYD(src).x, getXYD(src).y, getXYD(dst).x, getXYD(dst).y, 160);
                    move(destinationImage, getXYD(dst).x, getXYD(dst).y, getXYD(src).x, getXYD(src).y, 160);
                }
                // <
                var temp = place[src];
                place[src] = place[dst];
                place[dst] = temp;
                moves += 1;

                repaint();
                
                src = -1;
                dst = -1;
                fakeNeighS = -1;
                fakeNeighD = -1;
                
                if (isEnd() && animation == false && !lost) {
                    if (videopuzzle) {
                        for (i = 0; i < NUM*NUM; i++){
                            clearTimeout(window['videoloop'+i]);
                        }
                        (function loopend() {
                            if (!video.paused && !video.ended) {
                                ctx.drawImage(video, 0, 0, scaledW, canvas.height);
                                if (newHigh) {
                                    messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                                } else {
                                    messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                                }
                                videoendloop = setTimeout(loopend, 1000 / 30); // drawing at 30fps
                            }
                        })();
                    } else {
                        if (newHigh) {
                            messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                        } else {
                            messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                            cWon = true;
                        }
                    }
                    myTimer('pause');
                    cWon = true;
                    scores();
                }
                
                return false;
            }
        
            dst = -1;
            src = -1;
            fakeNeighS = -1;
            fakeNeighD = -1;
            messagePage.draw(LANG_ADJACENT);
        }
        return false;
    } else {
        if (activePage != 'game'){
            return;
        }
        // a játék vége után már ne kattintgasson
        if (mobile) {
            for (var i in event.touches) {
                var check = event.touches[i].clientX;
                if (check) {
                    var touch = event.touches[i];
                    cx = touch.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
                    cy = touch.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
                }
            }
        } else {
            cx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
            cy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
        }
        
        if (alertM == 1) {
            repaint();
            buttonRepaint() 
            alertM = 0;
            if (!timerStarted && !isEnd()) {
                myTimer('start');
            }
            if (isEnd() && videopuzzle) {
                clearTimeout(videoendloop);
            }
            return false;
        }

        if (lost) {
            return false;
        }
        
        if (isEnd()) {
            return false;
        }

        //képen kívüli rész
        if (cx > scaledW) {
            return false;
        }
        // nincs forrás kiválasztva
        if (src == -1) {
            //if (mode != 'challenge') {
                if (!timerStarted) {
                    myTimer("start");
                }
            //}
            src = getN(cx, cy);
            ctx.fillStyle = 'rgba('+Config.color+',0.5)';
            ctx.strokeStyle = 'rgba('+Config.color+',0.5)';
            ctx.lineWidth = SIZEX*0.02;
            if (!videopuzzle) {
                ctx.fillRect(getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
            }
            //ctx.strokeRect(getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
            if (mode == 'classic' && swapped) {
                animation = animold;
                swapped = false;
            }
            return false;
        }

        // ha van forrás kiválasztva
        if (src >= 0) {
            dst = getN(cx, cy);
            // ha forrás = cél, akkor kijelölés megszüntetése
            if (src == dst) {
                repaint();
                if (animation) {
                    object = new Menu();
                    for (i in place) {    
                        object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
                    }
                    object.draw();
                    if (hint == true) {
                        drawHint();
                    }
                    if (grid == true && !videopuzzle) {
                        imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
                        imageStroke.draw();
                    }
                }
                src = -1;
                dst = -1;
                return false;
            }
            
            // ha szomszédok, akkor csere
            if (szomszedok(src, dst)) {
                if (mode == 'classic') {
                    if (swapHint) {
                        swaps-=1;
                        swapHint=false;
                        swapIcon=imageOff;
                        swapped = true;
                    }
                }
                if (mode != "fun") {
                    hint = false;
                    hintIcon = imageOff;
                    buttonRepaint();
                }
                // animation >
                if (animation == true) {
                    sourceRect = new MyRectItem('sourcerect', getXYD(src).x, getXYD(src).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    destinationRect = new MyRectItem('destinationrect', getXYD(dst).x, getXYD(dst).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    sourceImage = new MyImageItem('source',kep, getXYS(place[src]).x, getXYS(place[src]).y, imageW, imageH, getXYD(src).x, getXYD(src).y, SIZEX, SIZEY);
                    destinationImage = new MyImageItem('destination',kep, getXYS(place[dst]).x, getXYS(place[dst]).y, imageW, imageH, getXYD(dst).x, getXYD(dst).y, SIZEX, SIZEY);
                    move(sourceImage, getXYD(src).x, getXYD(src).y, getXYD(dst).x, getXYD(dst).y, 160);
                    move(destinationImage, getXYD(dst).x, getXYD(dst).y, getXYD(src).x, getXYD(src).y, 160);
                }
                // <
                var temp = place[src];
                place[src] = place[dst];
                place[dst] = temp;
                moves += 1;

                repaint();
                
                src = -1;
                dst = -1;
                
                if (isEnd() && animation == false && !lost) {
                    if (videopuzzle) {
                        for (i = 0; i < NUM*NUM; i++){
                            clearTimeout(window['videoloop'+i]);
                        }
                        (function loopend() {
                            if (!video.paused && !video.ended) {
                                ctx.drawImage(video, 0, 0, scaledW, canvas.height);
                                if (newHigh) {
                                    messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                                } else {
                                    messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                                }
                                videoendloop = setTimeout(loopend, 1000 / 30); // drawing at 30fps
                            }
                        })();
                    } else {
                        if (newHigh) {
                            messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                        } else {
                            messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                            cWon = true;
                        }
                    }
                    myTimer('pause');
                    cWon = true;
                    scores();
                }
                
                return false;
            }
        
            dst = -1;
            src = -1;
            messagePage.draw(LANG_ADJACENT);
        }
        return false;
    }
});

canvas.addEventListener('touchmove',function(event) {
    event.preventDefault();
    for (var i in event.touches) {
		var check = event.touches[i].clientX;
		if (check) {
            var touch = event.touches[i];
            cx = touch.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
            cy = touch.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
		}
	}
});

canvas.addEventListener(eventup, function(event) {
    //~ var event = event.originalEvent;
    if (swipe) {
        if (activePage != 'game'){
            return;
        }
        // a játék vége után már ne kattintgasson
        //~ var touch = event.touches[0];
        //~ cx = touch.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
        //~ cy = touch.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
        if (!mobile) {
            cx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - canvas.offsetLeft; 
            cy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - canvas.offsetTop;
        }
        
        if (swapHint) {
            return;
        }
        
        if (alertM == 1) {
            return false;
        }

        if (lost) {
            return false;
        }
        
        if (isEnd()) {
            return false;
        }
        
        if (cx > scaledW) {
            src = -1;
            dst = -1;
            fakeNeighD = -1;
            repaint();
            repaint2();
            return;
        }
        
        // nincs forrás kiválasztva
        if (src == -1) {
            return false;
        }

        // ha van forrás kiválasztva
        if (src >= 0) {
            dst = getN(cx, cy);
            // ha forrás = cél, akkor kijelölés megszüntetése
            if (src == dst) {
                repaint();
                if (animation) {
                    object = new Menu();
                    for (i in place) {    
                        object.add(new MyImageItem(i,kep,getXYS(place[i]).x,getXYS(place[i]).y,imageW,imageH,getXYD(i).x,getXYD(i).y,SIZEX,SIZEY));
                    }
                    object.draw();
                    if (hint == true) {
                        drawHint();
                    }
                    if (grid == true && !videopuzzle) {
                        imageStroke = new MyGridItem('grid', 0, 0, scaledW, HEIGHT, NUM, NUM);
                        imageStroke.draw();
                    }
                }
                src = -1;
                dst = -1;
                fakeNeighS = -1;
                fakeNeighD = -1;
                return false;
            }
            
            // ha szomszédok, akkor csere
            if (szomszedok(src, dst)) {
            //    alert(fakeNeighD + "" + src + "" +dst);
                if (mode == 'classic') {
                    if (swapHint) {
                        swaps-=1;
                        swapHint=false;
                        swapIcon=imageOff;
                        swapped = true;
                    }
                }
                if (mode != "fun") {
                    hint = false;
                    hintIcon = imageOff;
                    buttonRepaint();
                }
                // animation >
                if (animation == true) {
                    sourceRect = new MyRectItem('sourcerect', getXYD(fakeNeighS).x, getXYD(fakeNeighS).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    destinationRect = new MyRectItem('destinationrect', getXYD(fakeNeighD).x, getXYD(fakeNeighD).y, SIZEX, SIZEY, 'rgba('+Config.backGround+',1)');
                    sourceImage = new MyImageItem('source',kep, getXYS(place[fakeNeighS]).x, getXYS(place[fakeNeighS]).y, imageW, imageH, getXYD(fakeNeighS).x, getXYD(fakeNeighS).y, SIZEX, SIZEY);
                    destinationImage = new MyImageItem('destination',kep, getXYS(place[fakeNeighD]).x, getXYS(place[fakeNeighD]).y, imageW, imageH, getXYD(fakeNeighD).x, getXYD(fakeNeighD).y, SIZEX, SIZEY);
                    move(sourceImage, getXYD(fakeNeighS).x, getXYD(fakeNeighS).y, getXYD(fakeNeighD).x, getXYD(fakeNeighD).y, 160);
                    move(destinationImage, getXYD(fakeNeighD).x, getXYD(fakeNeighD).y, getXYD(fakeNeighS).x, getXYD(fakeNeighS).y, 160);
                }
                // <
                var temp = place[fakeNeighS];
                place[fakeNeighS] = place[fakeNeighD];
                place[fakeNeighD] = temp;
                moves += 1;

                repaint();
                
                src = -1;
                dst = -1;
                fakeNeighS = -1;
                fakeNeighD = -1;
                
                if (isEnd() && animation == false) {
                    if (videopuzzle) {
                        for (i = 0; i < NUM*NUM; i++){
                            clearTimeout(window['videoloop'+i]);
                        }
                        (function loopend() {
                            if (!video.paused && !video.ended) {
                                ctx.drawImage(video, 0, 0, scaledW, canvas.height);
                                if (newHigh) {
                                    messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                                } else {
                                    messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                                }
                                videoendloop = setTimeout(loopend, 1000 / 30); // drawing at 30fps
                            }
                        })();
                    } else {
                        if (newHigh) {
                            messagePage.draw(LANG_NEWHIGHSCORE, LANG_SOLVED + ' ' + moves);
                        } else {
                            messagePage.draw(LANG_CONGRATS, LANG_SOLVED + ' ' + moves);
                            cWon = true;
                        }
                    }
                    myTimer('pause');
                    cWon = true;
                    scores();
                }
                
                return false;
            }
        
            dst = -1;
            src = -1;
            fakeNeighD = -1;
            fakeNeighS = -1;
            messagePage.draw(LANG_ADJACENT);
        }
        return false;
    }
});

function setNUM(s) {
    NUM = parseInt(s);
}

function selectImage(img) {
    if (videopuzzle) {
        $('#video').get(0).pause();
        $('#videosrc').attr('src',img);
        $('#video').get(0).load();
        return;
    } else {
        kep.src = img;
    }
}

window.onresize = function() {
    if (Config.fullScreen) {
        if (videopuzzle) {
            clearTimeout(videoendloop);
        }
        WIDTH = $(window).width();
        HEIGHT = $(window).height();
        $('canvas').attr('width', WIDTH);
        $('canvas').attr('height', HEIGHT);
        if (WIDTH < HEIGHT) {
            PORTRAIT = true;
        } else {
            PORTRAIT = false;
        }
        var maxW = WIDTH*0.8;
        if (PORTRAIT) {
            maxW = WIDTH;
        }
        if (Config.simpleMode) {
            maxW = WIDTH;
        }
        BSIZE = HEIGHT*0.1;
        if (BSIZE > 48) {
            BSIZE = 48;
        }
        
        if (videopuzzle) {
            imageW = video.videoWidth / NUM;
            imageH = video.videoHeight / NUM;
            kepW = Math.max(video.videoWidth, video.videoHeight);
            kepH = Math.min(video.videoWidth, video.videoHeight);
        } else {
            imageW = kep.width / NUM;
            imageH = kep.height / NUM;
            kepW = Math.max(kep.width, kep.height);
            kepH = Math.min(kep.width, kep.height);
        }
        ratio = kepW / kepH;
        
        scaledW = HEIGHT * ratio;
        if (maxW < scaledW) {
            scaledW = maxW;
        }
        if (Config.simpleMode) {
            scaledW = maxW;
        }
        SIZEX = scaledW / NUM;
        SIZEY = HEIGHT / NUM;
        
        if (PORTRAIT) {
            ctx.clearRect(0, 0, WIDTH, HEIGHT);
            messagePage.draw(LANG_WINDOW_SMALL);
            if (videopuzzle) {
                for (i = 0; i < NUM*NUM; i++){
                    clearTimeout(window['videoloop'+i]);
                }
                clearTimeout(videoendloop);
            }
            return;
        }

        if (activePage == 'main') {
            mainPage.draw();
            return;
        }
        if (activePage == 'selected') {
            imageSelectedPage.draw();
            return;
        }
        if (activePage == 'image') {
            imagePage.draw();
            return;
        }
        if (activePage == 'pack') {
            packPage.draw();
            return;
        }
        if (activePage == 'size') {
            sizePage.draw();
            return;
        }
        if (activePage == 'info') {
            infoPage.draw();
            return;
        }
        if (activePage == 'newgame') {
            newGamePage.draw();
            return;
        }
        if (activePage == 'game') {
            if (animation == true) {
                animation = false;
                animv = true;
            }
            repaint();
            repaint2();
            buttonRepaint();
            if (animv == true) {
                animation = true;
                animv = false;
            }
            return;
        }
    }
}
