from machine import Pin, I2C
import ssd1306, time, framebuf, network, socket, requests, json

import minicons as icon
import font8x16

# using default address 0x3C
i2c = I2C(sda=Pin(14), scl=Pin(12))

display = ssd1306.SSD1306_I2C(128, 64, i2c)


# network setup
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)
ap_if.active(False)
sta_if.active(True)
sta_if.connect('Wokwi-GUEST', '')

# weather api setup
apiKey = 'c4d9d0b2fceaa0707827026dec65f575'
cityName = 'St. Johns'
baseURL = "https://api.openweathermap.org/data/3.0/onecall?lat=47.523&lon=-52.923&exclude=minutely,hourly,daily&units=metric&appid="
completeURL = baseURL + apiKey
currentWeather = {}
x = {}

iconDict = {
    '01d' : icon.sun,
    '01n' : icon.moon,
    '02d' : icon.partlyCloudy,
    '02n' : icon.cloudy,
    '03d' : icon.cloudy,
    '03n' : icon.cloudy,
    '04d' : icon.cloudy,
    '04n' : icon.cloudy,
    '09d' : icon.rain,
    '09n' : icon.rain,
    '10d' : icon.rain,
    '10n' : icon.rain,
    '11d' : icon.rain,
    '11n' : icon.rain,
    '13d' : icon.snow,
    '13n' : icon.snow,
    '50d' : icon.cloudy,
    '50n' : icon.cloudy,
}


def getWeather():
    global x
    response = requests.get(completeURL)
    x = response.json()
    currentWeather['temp'] = x['current']['temp']
    currentWeather['feelsLike'] = x['current']['feels_like']
    currentWeather['humidity'] = x['current']['humidity']
    currentWeather['wind'] = {}
    currentWeather['wind']['speed'] = x['current']['wind_speed'] * 3.6 # convert to km/h
    currentWeather['wind']['deg'] = x['current']['wind_deg']
    currentWeather['weather'] = x['current']['weather']

cursorX = 0
cursorY = 0

def drawIcon(icon, x, y, incX=True, incY=False):
    global cursorX
    global cursorY
    iconBuffer = framebuf.FrameBuffer(icon.icon, icon.w, icon.h, framebuf.MONO_HLSB)
    display.blit(iconBuffer, x, y)
    if incX:
        cursorX += icon.w
    if incY:
        cursorY += icon.h

def drawString(string, x=cursorX, y=cursorY, incY=False):
    global cursorX
    global cursorY
    startX = cursorX
    chars = []
    for char in string:
        chars.append(font8x16.dict[char])
    cursorX = x
    for char in chars:
        drawIcon(char, cursorX, y)
    if incY:
        cursorX = startX
        charHeights = []
        for char in chars:
            charHeights.append(char.h)
        charHeights.sort()
        cursorY += charHeights[0]

def iconTest():
    drawIcon(icon.num0, 0, 0)
    drawIcon(icon.partlyCloudy, 16, 0)
    drawIcon(icon.cloudy, 32, 0)
    drawIcon(icon.rain, 48, 0)
    drawIcon(icon.snow, 64, 0)
    drawIcon(icon.moon, 80, 0)
    
    drawIcon(icon.degC, 0, 16)
    drawIcon(icon.degF, 8, 16)
    drawIcon(icon.humidity, 16, 16)

def weatherMockup():
    global cursorX
    global cursorY
    weatherIcon = icon.partlyCloudy

    display.text("MON", cursorX, cursorY)
    cursorY +=8
    drawIcon(weatherIcon, cursorX+4, cursorY, False, True)
    drawString(["2", "0", "degC"], cursorX, cursorY, True)
    drawIcon(icon.feelsLike, cursorX, cursorY, False, True)
    display.text("17", cursorX, cursorY)
    drawIcon(icon.degC, cursorX+16, cursorY)


def fillChecker():
    for i in range(display.width):
        for j in range(display.height):
            display.pixel(i, j, (i+j)%2)


def drawWeather(x, y):
    global cursorX
    cursorX = x
    global cursorY
    cursorY = y
    
    cursorX += 4
    drawIcon(iconDict[currentWeather['weather'][0]['icon']], cursorX, cursorY)
    cursorX += 5
    drawString(str(int(currentWeather['temp'])) + '@', cursorX, cursorY)
    cursorX = x
    cursorY += 16
    drawIcon(icon.feelsLike, cursorX, cursorY)
    cursorX += 1
    drawString(str(int(currentWeather['feelsLike'])) + '@', cursorX, cursorY)

while not sta_if.isconnected():
    print('.')
    time.sleep_ms(100)
getWeather()
drawWeather(0, 0)

display.show()