/*
 * Puzzle.fx
 *
 * Created on Oct 3, 2008, 6:24:44 PM
 */

package videopuzzle;

import javafx.scene.media.*;
import javafx.animation.*;
import javafx.geometry.*;
import javafx.scene.image.*;
import javafx.util.Sequences;
import java.lang.Math;

public class Puzzle {
    public var pieces:Piece[];
    public var video:MediaPlayer;
    public var width  = 300;
    public var height = 300;
    public var pieceWidth  = 300;
    public var pieceHeight = 300;
    public var pieceRows = 3;
    public var pieceCols = 3;
    public var scatterBounds:Rectangle2D = Rectangle2D { width: 300 height: 300 }
    public var selectedPiece:Piece = null;
    public var hintVisible = false;
    public-init var dragTargetImage:Image;
    public-init var ui:VideoPuzzleUI;

    init {
        generatePieces();
        scatter();
    }

    public function generatePieces() {
        pieces = for (x in [0..pieceCols-1]) {
                    for(y in [0..pieceRows-1]) {
                        Piece {
                            prow: y;
                            pcol: x;
                            px:x*pieceWidth py: y*pieceHeight
                            translateX: x*(pieceWidth+10) translateY:y*(pieceHeight+10)
                            video: video
                            puzzle: this
                            pw: pieceWidth ph: pieceHeight
                        }
                    }
                };
    }

    public function scatter() {
        for(piece in pieces) {
            piece.translateX = Math.random() * (scatterBounds.width-pieceWidth) + scatterBounds.minX;
            piece.translateY = Math.random() * (scatterBounds.height-pieceHeight) + scatterBounds.minY;
            piece.placed = false;
        }
    }

    public function toggleHint():Void {
        hintVisible = not hintVisible;
        if(hintVisible and selectedPiece != null) {
            var flash = Timeline {
                keyFrames: [
                    KeyFrame{time:0s action: function() { flashHints(true); } },
                    KeyFrame{time:0.5s action: function() { flashHints(false); } },
                ]
            };
            flash.play();
            selectedPiece.hintControlShowing = true;
        }
        if(not hintVisible) {
            for(pc in pieces) {
                pc.hintShowing = false;
                pc.hintControlShowing = false;
            }
        }
    }

    function flashHints(flashOn:Boolean):Void {
        var pc:Piece;
        pc = getPiece(selectedPiece.prow-1,selectedPiece.pcol);
        if(pc != null) { pc.hintShowing = flashOn; }
        pc = getPiece(selectedPiece.prow+1,selectedPiece.pcol);
        if(pc != null) { pc.hintShowing = flashOn; }
        pc = getPiece(selectedPiece.prow,selectedPiece.pcol-1);
        if(pc != null) { pc.hintShowing = flashOn; }
        pc = getPiece(selectedPiece.prow,selectedPiece.pcol+1);
        if(pc != null) { pc.hintShowing = flashOn; }
    }

    function getPiece(row:Integer, col:Integer):Piece {
        for(piece in pieces) {
            if(piece.prow == row and piece.pcol == col) {
                return piece;
            }
        }
        return null;
    }

    public function triggerHint(row:Integer, col:Integer, hintOn:Boolean):Void {
        var piece = getPiece(row,col);
        if(piece != null) {
            piece.hintShowing = hintOn;
        }
    }
}