#!/usr/bin/env python3

import math, os, ctypes
import sdl2, sdl2.sdlmixer, sdl2.sdlimage

class Win:
    # s, w, h, rect_ref
    # run_fps, run_t_end, run_t_begin, run_frame_t, run_frame_t_ms
    # window, windowsurface
    # event, event_ref
    # on_key, on_click, on_declick, on_move
    # draw

    def __init__ (self, w, h, s='win', run_fps = 60,
            on_key = None, on_click = None, on_declick = None, on_move = None):
        self.w, self.h = (w, h)
        self.s = s
        self.run_fps = run_fps
        self.on_key = on_key
        self.on_click = on_click
        self.on_declick = on_declick
        self.on_move = on_move
    
        self.keyc = sdl2.keycode.SDL_SCANCODE_UNKNOWN
        self.keys = [False] * sdl2.SDL_NUM_SCANCODES
        self.mx, self.my = (0, 0)
        self.mx_f, self.my_f = (0.0, 0.0)
        self.mb0_, self.mb1_, self.mb2_ = (False, False, False)

        if not self.create ():
            return None

    def create (self):
        self.draw = ctypes.cdll.LoadLibrary ('draw.so')
        if not self.draw:
            return False
    
        if sdl2.SDL_Init (sdl2.SDL_INIT_VIDEO):
            return False

        self.window = sdl2.SDL_CreateWindow (bytes(self.s, 'utf-8'),
            sdl2.SDL_WINDOWPOS_CENTERED, sdl2.SDL_WINDOWPOS_CENTERED,
            self.w, self.h, sdl2.SDL_WINDOW_SHOWN)
        if not self.window:
            return False

        self.windowsurface = sdl2.SDL_GetWindowSurface (self.window)

        # sdl2.mouse.SDL_ShowCursor (False)

        self.rect_ref = ctypes.byref (sdl2.SDL_Rect (0, 0,
            self.w, self.h))
 
        self.draw.draw_init (ctypes.c_void_p (
            self.windowsurface.contents.pixels), self.w, self.h)
        sdl2.SDL_UpdateWindowSurface (self.window)

        self.event = sdl2.SDL_Event ()
        self.event_ref = ctypes.byref (self.event)

        self.run_frame_t = 1.0 / self.run_fps
        self.run_frame_t_ms = int(self.run_frame_t * 1000.0)
        self.run_t_begin = self.run_t_end = sdl2.SDL_GetTicks ()
        return True

    def quit (self):
        sdl2.SDL_DestroyWindow (self.window)
        sdl2.SDL_Quit ()

    def tick (self):
        while sdl2.SDL_PollEvent (self.event_ref) != 0:
            if self.event.type == sdl2.SDL_QUIT:
                return False

            elif self.event.type == sdl2.SDL_KEYDOWN:
                if self.event.key.keysym.scancode ==\
                        sdl2.keycode.SDL_SCANCODE_ESCAPE:
                    return False

                self.keyc = self.event.key.keysym.scancode
                self.keys [self.keyc] = True

                if self.on_key:
                    self.on_key ()

            elif self.event.type == sdl2.SDL_KEYUP:
                self.keyc = sdl2.keycode.SDL_SCANCODE_UNKNOWN
                self.keys [self.keyc] = False

            elif self.event.type == sdl2.SDL_MOUSEBUTTONDOWN:
                if self.event.button.button == sdl2.SDL_BUTTON_LEFT:
                    self.mb0_ = True
                elif self.event.button.button == sdl2.SDL_BUTTON_RIGHT:
                    self.mb1_ = True
                elif self.event.button.button == sdl2.SDL_BUTTON_MIDDLE:
                    self.mb2_ = True
                self.mx = self.event.button.x
                self.my = self.event.button.y
                self.mx_f = (self.mx / self.w) - 0.5
                self.my_f = (self.my / self.h) - 0.5

                if self.on_click:
                    self.on_click ()
            
            elif self.event.type == sdl2.SDL_MOUSEBUTTONUP:
                self.mx = self.event.button.x
                self.my = self.event.button.y
                self.mx_f = (self.mx / self.w) - 0.5
                self.my_f = (self.my / self.h) - 0.5
                
                if self.on_declick:
                    self.on_declick ()

                if self.event.button.button == sdl2.SDL_BUTTON_LEFT:
                    self.mb0_ = False
                elif self.event.button.button == sdl2.SDL_BUTTON_RIGHT:
                    self.mb1_ = False
                elif self.event.button.button == sdl2.SDL_BUTTON_MIDDLE:
                    self.mb2_ = False

            elif self.event.type == sdl2.SDL_MOUSEMOTION:
                self.mx = self.event.motion.x
                self.my = self.event.motion.y
                self.mx_f = (self.mx / self.w) - 0.5
                self.my_f = (self.my / self.h) - 0.5

                if self.on_move:
                    self.on_move ()

        self.run_t_end = sdl2.SDL_GetTicks ()
        _t = self.run_t_begin - self.run_t_end + self.run_frame_t_ms
        if _t > 0:
            sdl2.SDL_Delay (_t)
        self.run_t_begin = sdl2.SDL_GetTicks ()
        return True

    def render (self):
        sdl2.SDL_UpdateWindowSurface (self.window)
        return True

