import RPi.GPIO as GPIO # import GPIO
import time #import time
from urllib2 import Request, urlopen, URLError #import URL tools
import pywapi #import weather api
import string #import string
import datetime #import date time lib
import json #import json lib for parsing
import unirest #import unirest
import math#import math
import threading #import threading for use with time

import Adafruit_CharLCD as LCD#import LCD screen and claim object

#initialize LCD
lcd = LCD.Adafruit_CharLCDPlate()

#this function uses pywapi and pings the NOAA site to recieve weather information from a hard coded
#station, station identities can be found at w1.weather.gov/xml/current_obs/seek.php?state=az&Find=Find
def weather():
    try: #try catch

        result = pywapi.get_weather_from_noaa('KPHL') #ping pywapi to contact NOAA

        weather = string.lower(result['weather']) + " \n" + result['temp_f'] + " F." #give parsed weather information

        lcd.message(weather) #print weather information to lcd screen

    except URLError, e: #if API cannot be contacted throw URL error
        lcd.message('could not connect to weather service'), e
        

#this function pings numbersapi to give trivia
def trivia():
    lcd.clear() #clear lcd screen
    request = Request('http://numbersapi.com/random/trivia') #request is from numbers API

    while True:
        try:
            response = urlopen(request) #use urlopen library to get response
            trivia = response.read() #read response from API

            while len(trivia) < 80:
        
                if len(trivia) > 60: #if entry is greater than 60 characters, break it up into two messages
                  s = trivia
                  lcd.message(s[0:len(trivia)/2])#slice trivia message in half and post first half

                  lcd.message("\n") #start new line

                  lcd.message(s[len(trivia)/2:len(trivia)]) #slice trivia and print second half
            
                else: #if message is small just print without breaking up
                  lcd.message(trivia) 

                while True: 
                    #loop through to use button
                    if lcd.is_pressed(LCD.SELECT): #while select button is pressed, scroll left
                        lcd.move_left()
                        time.sleep(.1)

                    elif ((lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.DOWN)) or (lcd.is_pressed(LCD.LEFT))):
                        break
                    else:
                        continue

                if ((lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.DOWN)) or (lcd.is_pressed(LCD.LEFT))):
                    break
                else:
                    continue
    
        except URLError, e: #if API cannot be contacted throw URL error
            lcd.message('could not connect to trivia api'), e

        if ((lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.DOWN)) or (lcd.is_pressed(LCD.LEFT))):
            break
        else:
            continue

                    
#this function calls a fact API and gives back a famous quote
def quote():
    lcd.clear() #clear LCD

    while True:
        try:
            response = unirest.post("https://andruxnet-random-famous-quotes.p.mashape.com/cat=famous", #use unirest to ping quote API
            headers=
                {
                    "X-Mashape-Key": "<your API key here>", #use API key from Mashape.com
                    "Content-Type": "application/x-www-form-urlencoded", #define content type
                    "accept": "application/json" #confirm JSON format
                },
                params={ "parameter": 23, "foo": "bar"}#parameters for JSON
                )

            quote = response.raw_body #create variable for raw JSON response
            json_string = quote #identify JSON response as string
            parsed_json = json.loads(quote)#create variable foor JSON parse

            quoteParse = (parsed_json['quote']) + " -" + (parsed_json['author']) #create variable for Parsed response

            while True: #as with trivia API, filter out responses of over 80 characters
                if len(quoteParse) > 80:
                    break
        
                elif len(quoteParse) > 60: #if length of parsed quote is over 60, break it up among two lines
                    s = quoteParse
                    lcd.message(s[0:len(quoteParse)/2]) #slice parsed message, post first half

                    lcd.message("\n") #new line

                    lcd.message(s[len(quoteParse)/2:len(quoteParse)]) #slice parsed message, post second half

                else: #if parsed quote is short, do nothing and just post quote
                    lcd.message(quoteParse)
    
                while True:
                   #loop through each button to check, as the select button is pressed, scroll left
                   if lcd.is_pressed(LCD.SELECT):
                       lcd.move_left()
                       time.sleep(.1)

                   elif (lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.UP)) or (lcd.is_pressed(LCD.LEFT)):
                        break
                   else:
                        continue

                if (lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.UP)) or (lcd.is_pressed(LCD.LEFT)):
                        break
                else:
                        continue
    
        except URLError, e: #if API cannot be contacted throw URL error
            lcd.message('could not connect to quote api'), e
            
        if (lcd.is_pressed(LCD.RIGHT))or (lcd.is_pressed(LCD.UP)) or (lcd.is_pressed(LCD.LEFT)):
            break
        else:
            continue
    
#this function calls a time API and gives accurate time based off of a timestamp generated from JSON

def giveTime():
    
    lcd.clear()
    try:
        response = unirest.get("http://api.timezonedb.com/?zone=America/New_York&format=json&key=<your API key here>", #receive time data from timezone API
        headers =
            {
            "key": "<your API key here>", #use key generated
            "accept": "application/json" #verify json response
            },
        )
        timeZone = response.raw_body #give raw JSON respons
        json_int = timeZone #parse timeStamp to integer to allow timestamp corrections
        parsed_json = json.loads(timeZone) #parse JSON call

        timeStamp = (parsed_json["timestamp"] + 14400) #timestamp plus offset
        
        value = datetime.datetime.fromtimestamp(timeStamp) #use timeStamp with date time library to format date and time

        readOut = (value.strftime('%Y-%m-%d %I:%M %p')) #format date and time
        
        lcd.message(readOut)  #readout formatted time data
       
    except URLError, e:
            lcd.message('could not contact time api'),e

      
#enter Main Method

lcd.message('Welcome to PiHub!')

while True:
            #loop through each button to check
    if lcd.is_pressed(LCD.RIGHT):
        lcd.clear()
        weather()
        

    if lcd.is_pressed(LCD.LEFT):
        lcd.clear()
        giveTime()
       

    if lcd.is_pressed(LCD.UP):
        lcd.clear()
        trivia()
        

    if lcd.is_pressed(LCD.DOWN):
        lcd.clear()
        quote()
        

##    if lcd.is_pressed(LCD.SELECT):
##        break

GPIO.cleanup()#clean up


