// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html
import * as cc from "cc";
import cp_palette_color_alpha from "./cp_palette_color_alpha";
import cp_palette_color_hue from "./cp_palette_color_hue";
import cp_palette_color_main from "./cp_palette_color_main";
import cp_palette_preview from "./cp_palette_preview";
import cp_palette_slider from "./cp_palette_slider";
import cp_palette_util from "./cp_palette_util";

const { ccclass, property } = cc._decorator;
export interface cp_palette_hsv {
    h: number;
    s: number;
    v: number;
}
export interface cp_palette_options {
    color: cc.Color;
    alpha: number;
    update_listener: (color: cc.Color, alpha: number) => void;
}
@ccclass
export default class cp_palette extends cc.Component {

    @property(cp_palette_color_hue)
    cp_palette_color_hue: cp_palette_color_hue = null;

    @property(cp_palette_color_main)
    cp_palette_color_main: cp_palette_color_main = null;

    @property(cp_palette_color_alpha)
    cp_palette_color_alpha: cp_palette_color_alpha = null;

    @property(cp_palette_preview)
    cp_palette_preview: cp_palette_preview = null;

    private options: cp_palette_options;

    density: number = 32;
    color: cc.Color = cc.Color.GRAY;
    alpha: number = 255;

    onLoad() {
        this.cp_palette_color_hue.cp_palette = this;
        this.cp_palette_color_main.cp_palette = this;
        this.cp_palette_color_alpha.cp_palette = this;
        this.cp_palette_preview.cp_palette = this;

        this.update_all();

        this.show({
            color: cc.Color.RED,
            alpha: 255,
            update_listener: () => { }
        });
    }

    show(options: cp_palette_options) {
        this.options = options;

        this.color = options.color.clone();
        this.alpha = options.alpha;

        this.node.active = true;

        this.cp_palette_preview.init(options);
        this.update_all();
    }

    hide() {
        this.node.active = false;
        this.options = null;
    }

    on_click_close() {
        this.hide();
    }

    // ======== get set

    get_hsv() {
        return this.color.toHSV();
    }

    set_color(color: cc.Color) {
        this.color.r = color.r;
        this.color.g = color.g;
        this.color.b = color.b;
    }

    set_hsv(h: number, s: number, v: number) {
        const color = new cc.Color().fromHSV(h, s, v);
        this.set_color(color);
    }

    set_r(v: number) {
        this.color.r = v;
    }

    set_g(v: number) {
        this.color.g = v;
    }

    set_b(v: number) {
        this.color.b = v;
    }

    // ======== update

    update_listener() {
        if (this.options) {
            this.options.update_listener(this.color.clone(), this.alpha);
        }
    }

    update_all() {
        this.update_color_hub();
        this.update_color_main();
        this.update_color_alpha();
        this.update_slider_rgba();
        this.update_preview();

        this.update_listener();
    }

    update_render_from_main() {
        this.update_slider_rgba();
        this.update_preview();

        this.update_listener();
    }

    private update_color_hub() {
        this.cp_palette_color_hue.update_sprite();
        this.cp_palette_color_hue.update_cursor();
    }

    private update_color_main() {
        this.cp_palette_color_main.update_sprite();
        this.cp_palette_color_main.update_cursor();

    }

    private update_color_alpha() {
        this.cp_palette_color_alpha.update_sprite();
        this.cp_palette_color_alpha.update_cursor();
    }

    private update_slider_rgba() {
        let comps = this.node.getComponentsInChildren(cp_palette_slider);
        for (let value of comps) {
            value.cp_palette = this;
            value.update_cursor();
        }
    }

    private update_preview() {
        this.cp_palette_preview.update_sprite();
    }

}