package ru.m.puzzlez.render;

import flash.display.GraphicsPathCommand;
import flash.display.Shape;
import flash.geom.Rectangle;
import flash.Vector;
import ru.m.puzzlez.core.Part;


class PartMask extends Shape {

    private static function createBound(commands:Vector<GraphicsPathCommand>, data:Vector<Float>, fromX:Float, fromY:Float, toX:Float, toY:Float, type:BoundType) {
        var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
        var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
        var boundLength = Math.max(Math.abs(toX - fromX), Math.abs(toY - fromY));
        var spikeWidth = boundLength * 0.2;
        var spikeOffset = (boundLength - spikeWidth) / 2;
        var spikeDepth = switch type {
            case NONE: 0;
            case IN: spikeWidth;
            case OUT: -spikeWidth;
        }
        switch type {
            case NONE:
            case IN | OUT:
                commands.push(GraphicsPathCommand.LINE_TO);
                data.push(fromX + spikeOffset * dx);
                data.push(fromY + spikeOffset * dy);
                commands.push(GraphicsPathCommand.LINE_TO);
                data.push(fromX + spikeOffset * dx - spikeDepth * dy);
                data.push(fromY + spikeDepth * dx + spikeOffset * dy);
                commands.push(GraphicsPathCommand.LINE_TO);
                data.push(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy);
                data.push(fromY + spikeDepth * dx  + (spikeOffset + spikeWidth) * dy);
                commands.push(GraphicsPathCommand.LINE_TO);
                data.push(fromX + (spikeOffset + spikeWidth) * dx);
                data.push(fromY + (spikeOffset + spikeWidth) * dy);
        }
        commands.push(GraphicsPathCommand.LINE_TO);
        data.push(toX);
        data.push(toY);
    }

    public var rect(default, null):Rectangle;

    public function new(rect:Rectangle, bound:Bounds) {
        super();
        graphics.beginFill(0xff00ff, 1);
        var commands = new Vector<GraphicsPathCommand>();
        var data = new Vector<Float>();
        commands.push(GraphicsPathCommand.MOVE_TO);
        data.push(rect.left);
        data.push(rect.top);
        createBound(commands, data, rect.left, rect.top, rect.right, rect.top, bound.top);
        createBound(commands, data, rect.right, rect.top, rect.right, rect.bottom, bound.right);
        createBound(commands, data, rect.right, rect.bottom, rect.left, rect.bottom, bound.bottom);
        createBound(commands, data, rect.left, rect.bottom, rect.left, rect.top, bound.left);
        graphics.drawPath(commands, data);
        graphics.endFill();
        this.rect = rect.clone();
        var offset = rect.width / 4 + rect.width * 0.05;
        this.rect.x -= offset;
        this.rect.y -= offset;
        this.rect.width += offset * 2;
        this.rect.height += offset * 2;
    }
}
