import pygame
import requests
from datetime import datetime

# Replace 'YOUR_API_KEY' with your actual OpenWeatherMap API key
api_key = 'Enter your API Key here'
base_url = 'http://api.openweathermap.org/data/2.5/weather'

# City name for which you want to get the weather
city_name = 'Enter Location Here'

# Parameters for the API request
params = {
    'q': city_name,
    'appid': api_key,
    'units':'imperial'  # Use'metric' for Celsius, 'imperial' for Fahrenheit
}

# Pygame setup
pygame.init()
x = 800
y = 480
screen = pygame.display.set_mode((x, y), pygame.FULLSCREEN)
clock = pygame.time.Clock()
running = True

time = 0

#font
font1 = pygame.font.Font('freesansbold.ttf', 32) #location
font2 = pygame.font.Font('freesansbold.ttf', 20) #block titles
font3 = pygame.font.Font('freesansbold.ttf', 26) #weather description
font4 = pygame.font.Font('freesansbold.ttf', 90) #main temperature
font5 = pygame.font.Font('freesansbold.ttf', 16) #other temperatures
font6 = pygame.font.Font('freesansbold.ttf', 70) #wind
font7 = pygame.font.Font('freesansbold.ttf', 24) #gust
font8 = pygame.font.Font('freesansbold.ttf', 50) #bottom row
font9 = pygame.font.Font('freesansbold.ttf', 12) #time stamp

#location text
locationText = font1.render(city_name, True, "white")
locationRect = locationText.get_rect()
locationRect.center = (x/2, 30)

#weather title text (block 1)
weatherText = font2.render("Weather", True, "white")
weatherRect = weatherText.get_rect()
weatherRect.center = (x/6, 80)

#temperature title text (block 2)
tempText = font2.render("Temperature", True, "white")
tempRect = tempText.get_rect()
tempRect.center = (x/2, 80)

#wind title text (block 3)
windText = font2.render("Wind", True, "white")
windRect = windText.get_rect()
windRect.center = (5*x/6, 80)

#pressure title text (block 4)
pressureText = font2.render("Pressure", True, "white")
pressureRect = pressureText.get_rect()
pressureRect.center = (x/6, y/2+100)

#humidity title text (block 5)
humidityText = font2.render("Humidity", True, "white")
humidityRect = humidityText.get_rect()
humidityRect.center = (x/2, y/2+100)

#visibility title text (block 6)
visibilityText = font2.render("Visibility", True, "white")
visibilityRect = visibilityText.get_rect()
visibilityRect.center = (5*x/6, y/2+100)

#weather icons
d01 = pygame.image.load('01d.png')
d02 = pygame.image.load('02d.png')
d03 = pygame.image.load('03d.png')
d04 = pygame.image.load('04d.png')
d09 = pygame.image.load('09d.png')
d10 = pygame.image.load('10d.png')
d11 = pygame.image.load('11d.png')
d13 = pygame.image.load('13d.png')
d50 = pygame.image.load('50d.png')

#wind direction icon
arrow = pygame.image.load('arrow.png')

#image center rotation
def blitRotateCenter(surf, image, topleft, angle):

    rotated_image = pygame.transform.rotate(image, angle)
    new_rect = rotated_image.get_rect(center = image.get_rect(topleft = topleft).center)

    surf.blit(rotated_image, new_rect)

#run script
while running:
    #quit event
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif pygame.key.get_pressed()[pygame.K_x]:
            running = False
            
    #time
    now = datetime.now()
    
    if time == 0:
        #api call
        response = requests.get(base_url, params=params)
        
        #screen reset
        screen.fill("black")
        
        #timestamp of last updated
        timeText1 = font9.render(f"Last updated: {now:%I:%M %p}", True, "white")
        timeRect1 = timeText1.get_rect()
        timeRect1.center = (700, 10)
        screen.blit(timeText1, timeRect1)
        
        #text
        screen.blit(locationText, locationRect)
        screen.blit(weatherText, weatherRect)
        screen.blit(tempText, tempRect)
        screen.blit(windText, windRect)
        screen.blit(pressureText, pressureRect)
        screen.blit(humidityText, humidityRect)
        screen.blit(visibilityText, visibilityRect)

        #dividers (6 blocks)
        pygame.draw.line(screen, "white", (x/3, 60), (x/3, y), 5)
        pygame.draw.line(screen, "white", (2*x/3, 60), (2*x/3, y), 5)
        pygame.draw.line(screen, "white", (0, y/2+80), (x, y/2+80), 5)
        
        #data
        if response.status_code == 200:
            #weather variables
            data = response.json()
            temperature = data['main']['temp']
            high = data['main']['temp_max']
            low = data['main']['temp_min']
            feels_like = data['main']['feels_like']
            humidity = data['main']['humidity']
            wind = data['wind']['speed']
            gust = data['wind']['gust']
            direction = data['wind']['deg']
            weather_description = data['weather'][0]['description']
            weather_icon = data['weather'][0]['icon']
            pressure = data['main']['pressure']
            humidity = data['main']['humidity']
            visibility = data['visibility']
            
            #icons
            if weather_icon == '01d' or weather_icon == '01n':
                d01_scaled = pygame.transform.scale(d01, (150, 150))
                screen.blit(d01_scaled, (55, 100))
            elif weather_icon == '02d' or weather_icon == '02n':
                d02_scaled = pygame.transform.scale(d02, (150, 150))
                screen.blit(d02_scaled, (55, 100))
            elif weather_icon == '03d' or weather_icon == '03n':
                d03_scaled = pygame.transform.scale(d03, (150, 150))
                screen.blit(d03_scaled, (55, 100))
            elif weather_icon == '04d' or weather_icon == '04n':
                d04_scaled = pygame.transform.scale(d04, (150, 150))
                screen.blit(d04_scaled, (55, 100))
            elif weather_icon == '09d' or weather_icon == '09n':
                d09_scaled = pygame.transform.scale(d09, (150, 150))
                screen.blit(d09_scaled, (55, 100))
            elif weather_icon == '10d' or weather_icon == '10n':
                d10_scaled = pygame.transform.scale(d10, (150, 150))
                screen.blit(d10_scaled, (55, 100))
            elif weather_icon == '11d' or weather_icon == '11n':
                d11_scaled = pygame.transform.scale(d11, (150, 150))
                screen.blit(d11_scaled, (55, 100))
            elif weather_icon == '13d' or weather_icon == '13n':
                d13_scaled = pygame.transform.scale(d13, (150, 150))
                screen.blit(d13_scaled, (55, 100))
            elif weather_icon == '50d' or weather_icon == '50n':
                d50_scaled = pygame.transform.scale(d50, (150, 150))
                screen.blit(d50_scaled, (55, 100))

            #weather description
            weatherDesc = font3.render(weather_description, True, "white")
            weatherDescRect = weatherDesc.get_rect()
            weatherDescRect.center = (x/6, 270)
            screen.blit(weatherDesc, weatherDescRect)

            #temperature
            tempDesc = font4.render(str(round(temperature))+"°F", True, "white")
            tempDescRect = tempDesc.get_rect()
            tempDescRect.center = (x/2, 180)
            screen.blit(tempDesc, tempDescRect)

            feelsDesc = font5.render("Feels like "+str(round(feels_like))+"°F", True, "white")
            feelsDescRect = feelsDesc.get_rect()
            feelsDescRect.center = (x/2, 240)
            screen.blit(feelsDesc, feelsDescRect)

            #wind
            scaledArrow = pygame.transform.scale(arrow, (70, 70))
            blitRotateCenter(screen, scaledArrow, (5*x/6-35, 185), 180-direction)
            
            windDesc = font6.render(str(round(wind))+"mph", True, "white")
            windDescRect = windDesc.get_rect()
            windDescRect.center = (5*x/6, 150)
            screen.blit(windDesc, windDescRect)

            gustDesc = font7.render("Gusting at "+str(round(gust))+"mph", True, "white")
            gustDescRect = gustDesc.get_rect()
            gustDescRect.center = (5*x/6, 270)
            screen.blit(gustDesc, gustDescRect)

            #pressure
            pressureDesc = font8.render(str(round(pressure))+"hPa", True, "white")
            pressureDescRect = pressureDesc.get_rect()
            pressureDescRect.center = (x/6, 410)
            screen.blit(pressureDesc, pressureDescRect)
            
            #humidity
            humidityDesc = font8.render(str(round(humidity))+"%", True, "white")
            humidityDescRect = humidityDesc.get_rect()
            humidityDescRect.center = (x/2, 410)
            screen.blit(humidityDesc, humidityDescRect)
            
            #visibility
            visibilityDesc = font8.render(str(round(visibility*6/10000))+" Miles", True, "white")
            visibilityDescRect = visibilityDesc.get_rect()
            visibilityDescRect.center = (5*x/6, 410)
            screen.blit(visibilityDesc, visibilityDescRect)
            
            print(data)
            print(time)
        else:
            print(f"Error: {response.status_code}")
        time += 1
    elif time >= 10000: #54000 - 15 minutes until next refresh (unless fps is low)
        time = 0
    else:
        time += 1

    print(time)
    
    #time
    timeText2 = font9.render(f"{now:%I:%M:%S %p}", True, "white")
    timeRect2 = timeText2.get_rect()
    timeRect2.center = (80, 10)
    pygame.draw.rect(screen, 'black', pygame.Rect(0,0,200,20))
    screen.blit(timeText2, timeRect2)
    
    #tick
    timeText3 = font9.render(str(time), True, "white")
    timeRect3 = timeText3.get_rect()
    timeRect3.center = (150, 10)
    screen.blit(timeText3, timeRect3)
    
    #render
    pygame.display.flip()

    clock.tick(60)

pygame.quit()
