import socket, time, json, sys, threading, traceback, requests, pygame, os, sys, io, base64
from render_page import output
#import dicts
from dicts import font_large as font
from datetime import datetime
from email.utils import formatdate
import threading
from http.server import ThreadingHTTPServer, SimpleHTTPRequestHandler


x = 0
y = 0
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (x,y)
pygame.init()
WIDTH = 1500
HEIGHT = 310
screen = pygame.display.set_mode([WIDTH,HEIGHT])#, pygame.FULLSCREEN)#, pygame.FULLSCREEN, pygame.NOFRAME)
R=3
ccol = (31,31, 31)
top = {}
bottom = {}
top_screen = pygame.Surface((12000, 33*5))
w=0

def strlen(thestring): 
    return sum((font[ascletters][0]) for ascletters in thestring)

def renderstring(thestring, dest=0):
    _string = thestring
    thestring = str(thestring)
    thestring = thestring.replace(")", "")
    thestring = thestring.replace("[", "")
    thestring = thestring.replace("]", "")
    thestring = thestring.replace("'", "")
    thestring = thestring.replace(",", "")
    top = {}
    s_len = strlen(thestring)
    top_screen = pygame.Surface((s_len*10, 33*5))
    if "list" in str(type(_string)): top_screen = pygame.Surface((WIDTH, 33*5))
    top_screen.fill(0)
    offs = 2
    pixwidth = 0
    loc = [top]
    for character in thestring:
        if not character in font: character = "_"
        for width in range(font[character][0]):
            for height in range(font["fontheight"]):
                invertedwidth = font[character][0] - width
                color = (font[character][height+1] >> invertedwidth) & 1
                try: top[width+pixwidth,height+offs] = color
                except: pass
                
        if isinstance(font[character][1],int): pixwidth += font[character][0]
        else: pixwidth += len(font[character][1])

    print("DEST: ", dest)
    if dest == 1:
        loc = top
        loc_screen = top_screen
        offs = 1
        offs_w = 1
    if dest == 0:
        loc = bottom
        loc_screen = bottom
        offs = 140
        offs_w = WIDTH*2
    
 
    for y in range(0,15):
        for x in range(0, 12000):
            try: 
                if int(loc[x,y]): ccol = (150,120,0)
                else: ccol = (0)
                if int(loc[x,y]) == 3: ccol = (0,0,255)
                #pygame.draw.circle(loc_screen,ccol,(x*10,y*10),4,3)
                pygame.draw.rect(loc_screen, ccol, pygame.Rect(x*10 - 2, y*10 - 2, 8, 8), 4)
                #screen.blit(loc_screen, (offs_w,1+offs))
            except Exception as e: 
                #print("Error: " ,e)
                pass
    screen.blit(loc_screen, (offs_w,1+offs))
    pygame.display.update()
    #pygame.image.save(top_screen, "top.jpeg")
    def surface_to_base64(surface, format="JPEG"):
        byte_io = io.BytesIO()
        pygame.image.save(surface, byte_io)  # This saves as TGA by default
        byte_io.seek(0)
        image_data = byte_io.read()

        # Convert TGA to JPEG using PIL
        from PIL import Image
        byte_io.seek(0)
        image = Image.open(byte_io)
        jpeg_io = io.BytesIO()
        image.save(jpeg_io, format=format)
        jpeg_io.seek(0)
        encoded_string = base64.b64encode(jpeg_io.read()).decode('utf-8')
        return encoded_string
    
    return surface_to_base64(loc_screen, format="JPEG")
    #pygame.image.save(varinit.bottom_screen, "bottom.jpeg")

    #return pixwidth

def handle_request(request, siteid = 0, out =  "Server-X: Access denied"):
    print(request.path)
    http_timestamp = formatdate(timeval=None, localtime=True, usegmt=True)
    try: 
        country = request.path.split("country=")[1].split("&")[0]
        operator = request.path.split("operator=")[1].split("&")[0]
        station = request.path.split("station=")[1].split("&")[0]
        out = json.dumps({"country": country, "operator": operator, "station": station})
    except: return
    try: screen = request.path.split("screen=")[1].split("&")[0]
    except: screen = None
    #print("Screen: ", screen)
    url = "http://data.t-skylt.se:90/get_departures?country="+country+"&operator="+operator+"&station="+station
    data = requests.get(url).text
    #print("Downloaded: " + data)
    data = json.loads(data)
    departures = []
    def converttime(ts, age = 0):
        return time.mktime(time.struct_time((int(ts[:4]),int(ts[5:7]),int(ts[8:10]),int(ts[11:13]),int(ts[14:16]),int(ts[17:19]) + int(age),0,-1,-1)))
    current_time = converttime(datetime.now().strftime('%Y-%m-%dT%H:%M:%S'))
    offset = 25*"("
    snip = 15
    for i in range(10):
        try: 
            _minsleft = round((converttime(data["departures"][i]["expected"]) - current_time)/60)
            minsleft = str(_minsleft) + " min"
            if int(_minsleft) > 0: 
                if len(departures) > 0: snip = None
                line = data["departures"][i]["line"]["id"]
                if not len(departures): 
                    offset = (138 - strlen(line + "((((((" + data["departures"][i]["destination"]))*"(" + "(((((((("
                else: offset = 25*"("
                
                
                
                all = line + "((((((" + data["departures"][i]["destination"][:snip] + offset + minsleft
                departures.append(all)
        except Exception as e: 
            print(e)
            break
        if i==0: offset = 5*" "
    print(departures)
    departure_1 = departures[0] 
    
    departure_list = {"1":renderstring(departure_1,1), "2":[]}

    for x, i in enumerate(departures):
        if x > 5: break
        if x > 0: departure_list["2"].append(i + "("*25)
    
    rest = str(departure_list["2"]).replace("'","").replace("[","").replace("]","").replace(",","")
    print(rest)
    departure_list["2"] = renderstring(rest,1)
    #img = renderstring("testABC",1)
    out = json.dumps(departure_list)
    out = output.replace("_TOPIMAGE", departure_list["1"]).replace("_BOTTOMIMAGE", departure_list["2"])
    
    out = out.replace("_TOPURL", "/country=se&operator=sl&station=9191&screen=1").replace("_BOTTOMURL", "/country=se&operator=sl&station=9191&screen=2")
    #out = output
    if screen == "1": out = departure_list["1"]
    if screen == "2": out = departure_list["2"]
    
    #print(img)
    request.wfile.write(bytearray("""HTTP/1.0 200 OK\n""" + 
                                """Date: """ + str(http_timestamp) + """\r\n""" + 
                                """Connection: close\r\n\r\n""" + 
                                out + "\n", "utf-8"))

def error_logger(request):
    with threading.Lock():
        try: handle_request(request)
        except Exception as e: print("Error: ", e)
    request.close_connection = True


SimpleHTTPRequestHandler.do_GET = error_logger
SimpleHTTPRequestHandler.timeout = 20

for port in [99]:
    try:
        server = ThreadingHTTPServer(("", port), SimpleHTTPRequestHandler)
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.daemon = True
        server_thread.start()
    except Exception as e: print(f"Not starting on port {port} due to: {e}")


#sys.exit()

while True:
    try: time.sleep(.01)
    except KeyboardInterrupt: sys.exit()
