package ru.m.puzzlez.render;

import flash.display.BitmapData;
import flash.display.Shape;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import haxework.net.ImageLoader;
import openfl.Assets;
import promhx.Promise;
import ru.m.puzzlez.core.ImageSource;
import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.render.mask.PartMask;

class RenderUtil {

    public static function resolveImage(source:ImageSource):Promise<BitmapData> {
        return switch source {
            case ASSET(name):
                return Promise.promise(Assets.getBitmapData(name));
            case URL(url):
                return new ImageLoader().GET(url);
        }
    }

    public static function cropImage(source:BitmapData, rect:Rectangle):BitmapData {
        var image = new BitmapData(Std.int(rect.width), Std.int(rect.height));
        var matrix = new Matrix();
        var scale = Math.max(rect.width / source.width, rect.height / source.height);
        matrix.scale(scale, scale);
        matrix.translate((rect.width - source.width * scale) / 2, (rect.height - source.height * scale) / 2);
        image.draw(source, matrix);
        return image;
    }

    public static function cropImagePart(source:BitmapData, part:Part):BitmapData {
        var rect = new Rectangle(part.rect.width * part.gridX, part.rect.height * part.gridY, part.rect.width, part.rect.width);
        var mask = new PartMask(rect, part.bounds);
        var canvas:Shape = new Shape();
        canvas.cacheAsBitmap = true;
        canvas.mask = mask;
        canvas.graphics.beginBitmapFill(source, null, false, true);
        canvas.graphics.drawRect(0, 0, source.width, source.height);
        canvas.graphics.endFill();
        var image = new BitmapData(Std.int(mask.rect.width), Std.int(mask.rect.height), true, 0x00000000);
        var matrix = new Matrix();
        matrix.translate(-mask.rect.x, -mask.rect.y);
        image.draw(canvas, matrix);
        var borderWidth = image.width * 0.02;
        var borderAlpha = 1.0;
        #if flash
        borderWidth /= 3;
        //borderAlpha = 0.5;
        #end
        image.applyFilter(image, image.rect, new Point(), new GlowFilter(0xffffff, 0.3, borderWidth, borderWidth, 8, 1, true));
        image.applyFilter(image, image.rect, new Point(), new GlowFilter(0x555555, 0.3, borderWidth / 2, borderWidth / 2, 16, 1, true));
        return image;
    }

    public static function containRectangle(source:Rectangle, target:Rectangle):Rectangle {
        var s = Math.min(1, Math.min(target.width / source.width, target.height / source.height));
        var width = source.width * s;
        var height = source.height * s;
        return new Rectangle((target.width - width) / 2, (target.height - height) / 2, width, height);
    }
}
