module ReadForcast
  where

import WeatherData
import ListUtils

--To read the date the predictions were made
forcastMadeOn :: [String] -> Date
forcastMadeOn = dataForDate

--To retrieve the number and date of the days forcasts were made on
-- This is determined by the number of "FCST"'s present between the 
-- two identifying words FCST and NORTHERN
getDays :: [String] -> String -> [Date]
getDays ls year = 
  let daySection = stripAfter "...NORTHERN" (stripTo "FCST" ls)
      fcstLists = separateToLists "FCST" ("FCST":daySection) 
      addWeekday = addOneToEach (snd fcstLists) (fst fcstLists) 1
      dateStringsLists = addTwoToEach (snd addWeekday) (fst addWeekday) 1 in
  map getDate (map (\x -> (reverse x)++[year]) (fst dateStringsLists))

{-getDays ["MM","INDICATES","MISSING","DATA","FCST","FCST","FCST","FCST","FCST",
         "FCST","FCST","FRI","SAT","SUN","MON","TUE","WED","THU","JAN","30",
         "JAN","31","FEB","01","FEB","02","FEB","03","FEB","04","FEB","05",    
         "...NORTHERN","UTAH...","SALT","LAKE","CITY"] "2004" =>
[(Date 30 "JAN" 2004),(Date 31 "JAN" 2004),(Date 1 "FEB" 2004),(Date 2 "FEB" 2004),
 (Date 3 "FEB" 2004),(Date 4 "FEB" 2004),(Date 5 "FEB" 2004)]-}

-- To create a forcast given the date made on, the date for, and
-- the list of strings from the page for that day
-- This string must be 5 elements long or an error will occur
makeForcast :: Date -> Date -> [String] -> Prediction
makeForcast on for (outlook:range:cop:_:null) =
 Predict on for (readOutlook outlook) (readRange range) (readChance cop)

--makeForcast (Date 30 "JAN" 2004) (Date 31 "JAN" 2004) ["PTCLDY","20/30","40","POP"] =>
--Predict (Date 30 "JAN" 2004) (Date 31 "JAN" 2004) (Cloudy Partly) (Range 20 30) (Chance 40)

-- To determine the outlook from n : possibly non-exhaustive
readOutlook :: String -> Outlook
readOutlook n = 
 case n of
  "PTCLDY" -> Cloudy Partly
  "MOCLDY" -> Cloudy Mostly
  "CLOUDY" -> Cloudy Full
  "SUNNY"  -> Sunny
  "SNOW"   -> Snow
  "RAIN"   -> Rain
  "TSTORM" -> Tstorms
  "FRZRAIN" -> FreezeRain

-- To record the temperature range from a string n/m
readRange :: String -> Range
readRange n =
 let preSlash = stripTo '/' n
     postSlash = stripAfter '/' n in
   Range (read postSlash) (read preSlash)

--readRange "20/30" => Range 20 30

-- To record the chance for percipitation from the string
readChance :: String -> CoP
readChance n = Chance (read n)

--readChance "40" => Chance 40

-- To separate the different days forcast information from the input strings
-- based on the format of the file
makeForcastLists :: [a] -> [[a]] -> [[a]]
makeForcastLists feed out =
 let addOutlook = addOneToEach feed out 1
     addRange = addOneToEach (snd addOutlook) (fst addOutlook) 1
     addPop = addTwoToEach (snd addRange) (fst addRange) 1 in
  map reverse (fst addPop)

{-makeForcastLists ["MOCLDY","MOCLDY","SNOW","PTCLDY","MOCLDY","PTCLDY","PTCLDY",   
                  "33/45","26/31","18/29","22/31","29/34","25/39","23/36",    
                  "POP","30","POP","20","POP","50","POP","30","POP","40","POP",
                  "20","POP","0"] [[][][][][][][]] =>  
[["MOCLDY","33/45","30","POP"],["MOCLDY","26/31","20","POP"],["SNOW","18/29","50","POP"],
 ["PTCLDY","22/31","30","POP"],["MOCLDY","29/34","40","POP"],["PTCLDY","25/39","20","POP"],
 ["PTCLDY","23/36","0","POP"]]
-}

-- To read the forcast from the input string ls
readForcast :: [String] -> [Prediction]
readForcast ls =
 let predictionDay = forcastMadeOn ls
     year = case predictionDay of Date d m y -> y
     daysPredictedFor = getDays ls (show year)
     predictions = makeForcastLists 
                   (stripAfter "OGDEN" (stripTo "CITY" (stripTo "...NORTHERN" ls)))
                   (map (\x -> []) daysPredictedFor) in 
  map (\t -> makeForcast predictionDay (fst t) (snd t)) 
      (zip daysPredictedFor predictions)

