##
# @package   gauge.py (from utils.py)
# @brief     Draw a simple Gauge Graphical Widget
# @author    Henry Daitx
# @date      Oct 2017
# @copyright Racelogic Ltd., 2017
#

import gui
import ft8xx as ft
from maths_utils import cosd, sind, lerp, Gauss_Filter as Filter

class Gauge:
    def __init__(self, x, y, d,
            vmin=0,
            vmax=100,
            dmin=180,
            dmax=45,
            ndivs=10,
            vred=None,
            color=gui.RGB(0, 0, 0),
            color_red=gui.RGB(246, 40, 23)):
        self.x = x
        self.y = y
        # d: 'characteristic dimension'
        self.d = d
        self.vmin = vmin
        self.vmax = vmax
        self.dmin = dmin
        self.dmax = dmax
        self.ndivs = ndivs
        self.vred = vred
        self.color = color
        self.color_red = color_red
        self.filter = Filter()
        self.gui_needle = [[0], [0], [0]]
        self.value = vmin
        self.update()

    def set_val(self, x):
        self.value = x
        self.update()

    def update(self):
        self.cur_val = self.filter(self.value)
        angle = lerp(self.cur_val, self.vmin, self.vmax, self.dmin, self.dmax)
        self.gui_needle[0][0] = gui.DL_VERTEX2F(
            self.x + .9 * self.d * cosd(angle),
            self.y - .9 * self.d * sind(angle)
        )
        self.gui_needle[1][0] = gui.DL_VERTEX2F(
            self.x + .05 * self.d * cosd(angle + 90),
            self.y - .05 * self.d * sind(angle + 90)
        )
        self.gui_needle[2][0] = gui.DL_VERTEX2F(
            self.x + .05 * self.d * cosd(angle - 90),
            self.y - .05 * self.d * sind(angle - 90)
        )

    def gui_l(self):
        ln = [gui.SUBLIST]
        # Draw numbers
        fontsize = int(lerp(self.d, 50, 250, 26, 32))
        if fontsize < 26:
            fontsize = 26
        elif fontsize > 31:
            fontsize = 31
        for i in range(self.ndivs + 1):
            angle = lerp(i, 0, self.ndivs, self.dmin, self.dmax)
            numval = int(lerp(i, 0, self.ndivs, self.vmin, self.vmax))
            if self.vred and numval >= self.vred:
                ln.append([gui.DL_COLOR(self.color_red)])
            ln.append([
                gui.CTRL_TEXT,
                int(self.x + .8 * self.d * cosd(angle)),
                int(self.y - .8 * self.d * sind(angle)),
                fontsize,
                gui.OPT_CENTER,
                str(numval)
            ])
        if self.vred:
            ln.append([gui.DL_COLOR(self.color)])
        # Draw ticks
        l = [gui.DL_SAVE_CONTEXT()]
        l.append(gui.DL_BEGIN(gui.PRIM_LINES))
        for i in range(self.ndivs + 1):
            angle = lerp(i, 0, self.ndivs, self.dmin, self.dmax)
            if i != 0:
                # Minor ticks
                angle_prev = lerp(i - 1, 0, self.ndivs, self.dmin, self.dmax)
                for j in range(1, 10):
                    angle_minor = lerp(j, 0, 10, angle_prev, angle)
                    if self.vred:
                        tickval = lerp(
                            angle_minor, self.dmin, self.dmax, self.vmin, self.vmax)
                        if tickval >= self.vred:
                            l.append(gui.DL_COLOR(self.color_red))
                    l.append(gui.DL_VERTEX2F(
                        self.x + self.d * cosd(angle_minor),
                        self.y - self.d * sind(angle_minor)
                    ))
                    f = .99 if j != 5 else .97
                    l.append(gui.DL_VERTEX2F(
                        self.x + f * self.d * cosd(angle_minor),
                        self.y - f * self.d * sind(angle_minor)
                    ))
            # Major ticks
            l.append(gui.DL_VERTEX2F(
                self.x + self.d * cosd(angle),
                self.y - self.d * sind(angle)
            ))
            l.append(gui.DL_VERTEX2F(
                self.x + .92 * self.d * cosd(angle),
                self.y - .92 * self.d * sind(angle)
            ))
        l.append(gui.DL_END())
        if self.vred:
            l.append(gui.DL_COLOR(self.color))
        # Draw needle
        # Filled polygon
        l.extend([
            gui.DL_STENCIL_OP(ft.STENCILOP_INCR, ft.STENCILOP_INCR),
            gui.DL_COLOR_MASK(0, 0, 0, 0),
            gui.DL_BEGIN(gui.PRIM_EDGE_STRIP_B),
            self.gui_needle[0],
            self.gui_needle[1],
            self.gui_needle[2],
            self.gui_needle[0],
            gui.DL_END(),
            gui.DL_COLOR_MASK(1, 1, 1, 1),
            gui.DL_STENCIL_FUNC(ft.ALPHAFUNC_EQUAL, 1, 255),
            gui.DL_BEGIN(gui.PRIM_EDGE_STRIP_B),
            self.gui_needle[0],
            self.gui_needle[1],
            self.gui_needle[2],
            self.gui_needle[0],
            gui.DL_END(),
            gui.DL_STENCIL_FUNC(ft.ALPHAFUNC_ALWAYS, 0, 255),
            gui.DL_CLEAR(0, 1, 0),
        ])
        # Outline
        l.extend([
            gui.DL_LINE_WIDTH(1.6),
            gui.DL_BEGIN(gui.PRIM_LINE_STRIP),
            self.gui_needle[0],
            self.gui_needle[1],
            self.gui_needle[2],
            self.gui_needle[0],
            gui.DL_END()
        ])
        # Draw center pivot
        l.extend([
            gui.DL_POINT_SIZE(self.d * .08),
            gui.DL_BEGIN(gui.PRIM_POINTS),
            gui.DL_VERTEX2F(self.x, self.y),
            gui.DL_END()
        ])
        l.append(gui.DL_RESTORE_CONTEXT())
        ln.append(l)
        return ln



#end