import gui
from screen_base import ScreenBase

# You have to have the BebasNeue_0-50.rft font in your spifi otherwise there will be a font load error, you also cannot replace the font in position 12

# def load_font_50():
#     from font import load_font
#     import os
#     path = os.getcwd() + '/'
#     start, end = load_font(path+'BebasNeue_0-50.rft', 12)
#     return start

class Position:
    HIDE = 800
    COL0 = 20
    COL1 = 130
    COL2 = 240
    COL3 = 350
    COL4 = 460
    COL5 = 570
    COL6 = 680
    ROW0 =  85
    ROW1 = 165
    ROW2 = 245
    ROW3 = 325

class Size:
    WIDTH = 100
    HEIGHT = 70

class ScreenValue(ScreenBase):
    def __init__(self):
        super().__init__()
        self.unit_title = ['']

        self.max_len = 11
        self.max = 99999999
        self.min = -99999999
        self.flag_first_press = False

        self.input_chars = {
            '1'     :   [Position.COL0, Position.ROW0],
            '2'     :   [Position.COL1, Position.ROW0],
            '3'     :   [Position.COL2, Position.ROW0],
            '4'     :   [Position.COL0, Position.ROW1],
            '5'     :   [Position.COL1, Position.ROW1],
            '6'     :   [Position.COL2, Position.ROW1],
            '7'     :   [Position.COL0, Position.ROW2],
            '8'     :   [Position.COL1, Position.ROW2],
            '9'     :   [Position.COL2, Position.ROW2],
            '0'     :   [Position.COL1, Position.ROW3],
            '\x7F'  :   [Position.COL6, Position.ROW1],
            'CLEAR' :   [Position.COL6, Position.ROW2],
            'X'     :   [Position.COL5, Position.ROW3], 
            '\x1A'  :   [Position.COL6, Position.ROW3],
            '+/-'   :   [Position.COL0, Position.ROW3], 
            '.'     :   [Position.COL2, Position.ROW3],
        }

        self.input_chars_display = []

        self.text_bkgnd = [
            gui.DL_COLOR_RGB(200, 200, 200),
            gui.DL_LINE_WIDTH(15),
            gui.DL_BEGIN(gui.PRIM_RECTS),
            gui.DL_VERTEX2F(380, 105),
            gui.DL_VERTEX2F(770, 127),
        ]
        self.text_colour = [gui.DL_COLOR_RGB(0,0,0)]
        self.text = [gui.CTRL_TEXT, 770, 90, 12, gui.OPT_RIGHTX, '+']

    def setup(self):
        super().setup()
        self.gui_list.extend([
            self.text_bkgnd,
            self.text_colour,
            self.text,
            [gui.DL_COLOR_RGB(255,255,255)],
            [gui.CTRL_TEXT, 770, 13, 31, 2048, self.unit_title],
        ])
        
        self.generate_input_chars_display()


    def vsync_cb(self, l):
        self.check_text()
        super().vsync_cb(l)

    def generate_input_chars_display(self):
        for keys, values in self.input_chars.items():
            self.gui_list.extend([[gui.CTRL_BUTTON, values[0], values[1], Size.WIDTH, Size.HEIGHT, 12, keys, self.decode_char]])

    def clear_text(self):
        self.text[5] = self.text[5][0]

    def check_text(self):
        try:
            if float(self.text[5]) > self.max or float(self.text[5]) < self.min:
                self.text_colour[0] = gui.DL_COLOR_RGB(128,0,0)
            elif self.text_colour[0] == gui.DL_COLOR_RGB(128,0,0):
                self.text_colour[0] = gui.DL_COLOR_RGB(0,0,0)
        except ValueError:
            self.text_colour[0] = gui.DL_COLOR_RGB(0,0,0)

    def decode_char(self, button_details):
        try:
            has_negative = True
        except KeyError:
            has_negative = False
            
        if button_details[6] == '+/-': # switch the signs
            if has_negative:
                if self.text[5][0] == '+':
                    self.text[5] = '-'+self.text[5][1:]
                else:
                    self.text[5] = '+'+self.text[5][1:]
            else:
                self.text[5] = ' '+self.text[5][1:]

        elif button_details[6] == '\x7F': # backspace
            if len(self.text[5]) > 1:
                self.text[5] = self.text[5][:-1]

        elif button_details[6] == 'CLEAR': # clear the text
            self.clear_text()

        elif button_details[6] == 'X': # cancel
            self.exit_func()

        elif button_details[6] == '\x1A': # confirm
            if self.text_colour[0] == gui.DL_COLOR_RGB(0,0,0) and len(self.text[5]) > 1: # Only sends if valid
                self.confirm_func(self.text[5])

        elif len(self.text[5]) <= self.max_len: # 10 nums and the sign
            if self.flag_first_press == False:
                self.flag_first_press = True
                self.clear_text()
            if button_details[6] == '.':
                if '.' in self.text[5] or self.max_dp == 0: # if there is already a '.' then there can't be another
                    pass
                else:
                    if len(self.text[5]) <= 1: # if there is no other data then add a 0 in front
                        self.text[5] += '0.'
                    else:
                        self.text[5] += '.'

            else:
                if len(self.text[5]) > 1: # if there is a value after the +/-
                    if button_details[6] == '0': # if it is a 0
                        if self.text[5][1] != '0': # if the current 
                            self.text[5] += '0'
                        else:
                            try:
                                if self.text[5][2] == '.': # checks if it is 0.
                                    if len(self.text[5].split('.')[1]) < self.max_dp:
                                        self.text[5] += '0' # adds a 0 if it is
                            except IndexError:
                                pass

                    else: # if it is a number that isn't 0
                        if self.text[5][1] == '0': # if there is currently a 0 after the +/-
                            try:
                                if self.text[5][2] == '.': # and it is '0.'
                                    if len(self.text[5].split('.')[1]) < self.max_dp:
                                        self.text[5] += button_details[6] # add the number regularly
                            except IndexError:
                                self.text[5] = self.text[5][0] + button_details[6] # replace the 0 with the number added

                        else:
                            try:
                                if len(self.text[5].split('.')[1]) < self.max_dp:
                                    self.text[5] += button_details[6] # if it isn't a zero then add the number
                            except IndexError:
                                self.text[5] += button_details[6] # add the number regularly

                else: # if there isn't a value after the +/- then add one whatever it is
                    self.text[5] += button_details[6]

    def configure(self, start_val, confirm_func, exit_func, min_val, max_val, max_dp = 1, title = '', unit_title = ''):
        float(start_val)
        start_val = str(start_val)
        int(min_val)
        int(max_val)
        int(max_dp)
        try:
            if len(start_val.split('.')[1]) > max_dp:
                start_val = start_val[:len(start_val.split('.')[0])+max_dp+(1 if max_dp!=0 else 0)]
        except IndexError:
            pass
            
        if len(start_val) > self.max_len:
            start_val = start_val[:self.max_len-1]

        if not callable(confirm_func):
            raise TypeError("Confirm function is not a callable function")
        if not callable(exit_func):
            raise TypeError("Exit function is not a callable function")
        if min_val >= max_val:
            raise ValueError("Min cannot be greater than or equal to max")
        
        self.confirm_func = confirm_func
        self.exit_func = exit_func
        self.title[0] = str(title)
        self.unit_title[0] = str(unit_title)
        self.min = min_val
        self.max = max_val
        self.max_dp = max_dp
        if self.max_dp > 0:
            self.input_chars['.'] = [Position.COL2, Position.ROW3]
        else:
            try:
                self.input_chars.pop('.')
            except KeyError:
                pass
        if self.min < 0:
            self.input_chars['+/-'] = [Position.COL0, Position.ROW3]
            if len(start_val):
                self.text[5] = start_val if start_val[0] == '+' or start_val[0] == '-' else '+'+start_val
            else:
                self.text[5] = '+'
        else:
            if len(start_val):
                self.text[5] = ' '+start_val
            else:
                self.text[5] = ' '
            try:
                self.input_chars.pop('+/-')
            except KeyError:
                pass

        self.flag_first_press = False

# def confirm(num):
#     print("RECEIVED: {}".format(num))

# def exit():
#     print("EXITED")      

# if __name__ == '__main__':
#     load_font_50()
#     val = ScreenValue()
#     val.configure(100, confirm, exit, -100, 100, 'HELLO')
#     val.setup()
#     gui.show(val.gui_list)
