import {Component, Output, EventEmitter, OnInit, Input} from "@angular/core";
import { fabric } from 'fabric';

@Component({
    selector: 'signature-drawer',
    templateUrl: './signature-drawer.component.html',
    styleUrls:['./signature-drawer.component.css']
})
export class SignatureDrawerComponent  implements OnInit
{
    @Output() signatureDrawn$ = new EventEmitter<string>()

    size = 320;
    canvas: any;
    isEditImage = false;
    isDrawing = false;
    canDelete = false;
    currentColor = "rgba(0,0,0,1)";
    currentAlpha = 1;
    currentThickness = 4;

    elements : any[] = [];

    ngOnInit() {
        this.canvas = new fabric.Canvas('signatureCanvas');
        let self = this;
        this.canvas.on({
          'selection:updated': function() {self.handleElement()},
          'selection:created': function() {self.handleElement()}
        });

        const image = localStorage.getItem('signature_image');
        if (image) {
            fabric.Image.fromURL(image , function(img: any) {
                self.canvas.add(img);
                self.canvas.renderAll();
            })
        }
    }

    toggleDrawing() {
        if (this.isDrawing) {
            this.isDrawing = false;
            this.canvas.isDrawingMode = false;
        } else {
            this.canvas.discardActiveObject().renderAll();
            this.isEditImage = false;
            this.isDrawing = true;
            this.canvas.isDrawingMode = true;
            let brush = this.canvas.freeDrawingBrush;
            brush.color = this.currentColor;
            brush.width = this.currentThickness;
        }

        //this.canvas.freeDrawingBrush.width
        //this.canvas.freeDrawingBrush.shadow.blur = parseInt(this.value, 10)
    }

    handleElement(){
        let selectedObjects = this.canvas.getActiveObject();

        if (selectedObjects.hasOwnProperty("filters")) {
            this.isEditImage = true;
        } else {
            this.isEditImage = false;
        }
    }

    updateColor(value: string) {
        if (typeof value == "object") {
            return;
        }
        this.currentColor = value;

        for (let o of this.getSelectedObjects()) {
            this.updateColorFilter(o);
        }

        let brush = this.canvas.freeDrawingBrush;
        brush.color = this.currentColor;

        this.canvas.renderAll();
    }

    updateAlpha(value: number) {
        if (typeof value == "object") {
            return;
        }
        this.currentAlpha = value;

        for (let o of this.getSelectedObjects()) {
            o.opacity = this.currentAlpha;
        }

        this.canvas.renderAll();
    }

    updateThickness(value: string) {
        this.currentThickness = +value

        let brush = this.canvas.freeDrawingBrush;
        brush.width = this.currentThickness;
    }

    getSelectedObjects(): any[] {
        let obj = this.canvas.getActiveObject();
        if (obj === undefined || obj === null) {
            return []
        } else if (obj.hasOwnProperty("_objects")) {
             return obj._objects;
        } else {
            return [obj];
        }
    }

    updateColorFilter(o: any) {
        if (o.hasOwnProperty("filters")) {
            for (let f of o.filters) {
                if (f.type == "BlendColor") {
                    f.color = this.currentColor;
                }
            }
            o.applyFilters()
        }
    }

    addImage(event: any) {
        let file = event.target.files[0]
        let url = URL.createObjectURL(file);

        let self = this;
        fabric.Image.fromURL(url, function(img: any) {
            let scale;
            if (img.width > img.height) {
                img.scaleToWidth(self.size, true);
                scale = self.size / img.width;
            } else {
                img.scaleToHeight(self.size, true);
                scale = self.size / img.height;
            }

            let resizeFilter = new fabric.Image.filters.Resize(({
                resizeType: 'sliceHack',
                scaleX: scale,
                scaleY: scale
            }));

            //img.filters.push(resizeFilter);
            img.filters.push(new fabric.Image.filters.Grayscale());

            // @ts-ignore
            img.filters.push(new fabric.Image.filters.RemoveColor())
            img.filters.push(new fabric.Image.filters.BlendColor({
                 color: self.currentColor,
                 mode: 'lighten',
            }));
            img.applyFilters();
            self.canvas.add(img);
            self.canvas.renderAll();

            self.elements.push(img);
            event.target.value = "";
        });
    }

    delete() {
        this.canvas.remove(this.canvas.getActiveObject());
    }

    clear() {
        this.canvas.clear();
    }

    sign() {
        const image = this.canvas.toDataURL({
            format: 'png',
            quality: 0.8
        });
        localStorage.setItem('signature_image', image);
        this.signatureDrawn$.next(image)
    }
}

@Component({
    selector: 'color-range',
    template: `
        <div>
            <label for="colorRange" class="form-label">Color</label>
            
            <input type="range" class="form-range" #colorRange [value]="this.currentColorRatio" max="255" (input)="this.updateColor(colorRange.value)">
            <div class="input-group">
                <input class="form-control" type="text" #colorInput [value]="this.currentColorRatio" (change)="this.updateColor(colorInput.value)">
                <span class="input-group-text" #colorShow [style.background-color]="this.value" style="width: 40px">&nbsp;</span>
            </div>
        </div>
    `
})
export class BlackBlueRangeComponent implements OnInit
{
    @Output() change = new EventEmitter<string>();

    currentColorRatio = 255;
    @Input() value = `rgba(0,0,${this.currentColorRatio},1)`;

    ngOnInit() {
        let rgbArr = this.value.substring(4, this.value.length-1).replace(/ /g, '').split(',');
        this.currentColorRatio = +rgbArr[2];
    }

    updateColor(value: string) {
        this.currentColorRatio = +value;
        this.value = `rgb(0,0,${this.currentColorRatio})`;

        this.change.emit(this.value)
    }
}

@Component({
    selector: 'alpha-range',
    template: `
            <label for="alphaRange" class="form-label">Opacity</label>
            <input type="range" class="form-range" #alphaRange [value]="this.currentAlphaRatio" max="100" (input)="this.updateAlpha(alphaRange.value)">
            <input class="form-control" type="text" #alphaInput [value]="this.currentAlphaRatio" (change)="this.updateAlpha(alphaInput.value)">
    `
})
export class AlphaRangeComponent implements OnInit
{
    @Output() change = new EventEmitter<number>();

    currentAlphaRatio = 100;

    @Input() value = this.currentAlphaRatio / 100;

    ngOnInit() {
        this.currentAlphaRatio = this.value * 100;
    }

    updateAlpha(value: string) {
        this.currentAlphaRatio = +value;
        this.value = this.currentAlphaRatio / 100;

        this.change.emit(this.value)
    }
}
