<template>
    <canvas id="clockItem1" width="400" height="400" />
</template>

<script lang="ts">
    import { SGraphItem, SGraphScene, SGraphView } from "@persagy-web/graph";

    import {
        SColor,
        SLineCapStyle,
        SPainter,
        SRect,
        SSize
    } from "@persagy-web/draw";

    class SGraphClockItem extends SGraphItem {
        /** 大小 */
        size: SSize;

        /** 宽度 */
        get width() {
            return this.size.width;
        } // Get width
        set width(v: number) {
            this.size.width = v;
        } // Set width

        /** 高度 */
        get height() {
            return this.size.height;
        } // Get width
        set height(v: number) {
            this.size.height = v;
        } // Set width

        /** 半径 */
        get radius() {
            return Math.min(this.width, this.height) / 2.0;
        } // Get radius

        /**
         * 构造函数
         *
         * @param   parent      指向父Item
         * @param   size        大小
         */
        constructor(parent: SGraphItem | null, size: SSize);

        /**
         * 构造函数
         *
         * @param   parent      指向父Item
         * @param   width       宽度
         * @param   height      高度
         */
        constructor(parent: SGraphItem | null, width: number, height: number);

        /**
         * 构造函数
         *
         * @param   parent      指向父Item
         * @param   width       宽度
         * @param   height      高度
         */
        constructor(
            parent: SGraphItem | null,
            width: number | SSize,
            height?: number
        ) {
            super(parent);
            if (width instanceof SSize) {
                this.size = new SSize(width.width, width.height);
            } else {
                this.size = new SSize(width as number, height as number);
            }
        } // Constructor()

        /**
         * 对象边界区域
         *
         * @return  边界区域
         */
        boundingRect(): SRect {
            return new SRect(0, 0, this.width, this.height);
        } // Function SRect()

        /**
         * Item绘制操作
         *
         * @param   painter       painter对象
         */
        onDraw(painter: SPainter): void {
            painter.translate(this.width / 2, this.height / 2);
            let t = new Date();

            this.drawScale(painter);
            this.drawHour(painter, t.getHours(), t.getMinutes(), t.getSeconds());
            this.drawMinute(painter, t.getMinutes(), t.getSeconds());
            this.drawSecond(painter, t.getSeconds() + t.getMilliseconds() / 1000.0);

            this.update()
        } // Function onDraw()

        /**
         * 绘制表刻度
         *
         * @param   painter     painter对象
         */
        private drawScale(painter: SPainter): void {
            let scaleLength = Math.max(this.radius / 10.0, 2.0);
            let scaleLength1 = scaleLength * 1.2;
            let strokeWidth = Math.max(this.radius / 100.0, 2.0);
            let strokeWidth1 = strokeWidth * 2.0;

            painter.save();
            painter.pen.color = SColor.Blue;

            for (let i = 1; i <= 12; i++) {
                // 12小时刻度
                painter.pen.lineWidth = strokeWidth1;
                painter.drawLine(0, -this.radius, 0, -this.radius + scaleLength1);

                if (this.radius >= 40) {
                    // 如果半度大于40显示分钟刻度
                    painter.rotate(6);
                    for (let j = 1; j <= 4; j++) {
                        // 分钟刻度
                        painter.pen.lineWidth = strokeWidth;
                        painter.drawLine(
                            0,
                            -this.radius,
                            0,
                            -this.radius + scaleLength
                        );
                        painter.rotate(6);
                    }
                } else {
                    painter.rotate(30);
                }
            }

            painter.restore();
        } // Function drawScale()

        /**
         * 绘制时针
         *
         * @param   painter     painter对象
         * @param   hour        时
         * @param   minute      分
         * @param   second      秒
         */
        private drawHour(
            painter: SPainter,
            hour: number,
            minute: number,
            second: number
        ): void {
            painter.save();
            painter.pen.lineCapStyle = SLineCapStyle.Round;
            painter.pen.lineWidth = Math.max(this.radius / 30.0, 4.0);
            painter.rotate(
                hour * 30.0 + (minute * 30.0) / 60 + (second * 30.0) / 3600
            );
            painter.drawLine(0, this.radius / 10.0, 0, -this.radius / 2.0);
            painter.restore();
        } // Function drawHour()

        /**
         * 绘制秒针
         *
         * @param   painter     painter对象
         * @param   minute      分
         * @param   second      秒
         */
        private drawMinute(
            painter: SPainter,
            minute: number,
            second: number
        ): void {
            painter.save();
            painter.pen.lineCapStyle = SLineCapStyle.Round;
            painter.pen.lineWidth = Math.max(this.radius / 40.0, 4.0);
            painter.rotate(minute * 6 + (second * 6) / 60.0);
            painter.drawLine(0, this.radius / 10.0, 0, (-this.radius * 2.0) / 3.0);
            painter.restore();
        } // Function drawMinute()

        /**
         * 绘制秒针
         *
         * @param   painter     painter对象
         * @param   second      秒
         */
        private drawSecond(painter: SPainter, second: number): void {
            painter.save();
            painter.pen.lineCapStyle = SLineCapStyle.Round;
            painter.pen.lineWidth = Math.max(this.radius / 100.0, 3.0);
            painter.pen.color = SColor.Red;
            painter.rotate(second * 6);
            painter.drawLine(
                0,
                this.radius / 5.0,
                0,
                -this.radius + this.radius / 10.0
            );
            painter.restore();
        } // Function drawSecond()
    } // Class SGraphClockItem

    class TestView extends SGraphView {
        clock1 = new SGraphClockItem(null, 300, 300);

        constructor() {
            super("clockItem1");
            this.scene = new SGraphScene();
            this.scene.addItem(this.clock1);
        }
    }

    export default {
        mounted(): void {
            new TestView();
        }
    }
</script>

<style scoped>

</style>
