{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE RankNTypes #-}
{-# OPTIONS -fno-warn-unused-imports #-}

module L where

import Control.Applicative
import Control.Arrow
import Control.Monad
import Data.Char
import Data.Function
import Data.Functor
import Data.List
--import Data.List.Split
import Data.Maybe
import Data.Monoid
import Data.Ratio
import Data.Word
import Network.URI
import Numeric
import Prelude
import Text.Printf

interleave :: [a] -> [a] -> [a]
interleave []     _  = []
interleave (x:xs) ys = x : interleave ys xs

padl :: Int -> a -> [a] -> [a]
padl n p s = pad n p s ++ s

padr :: Int -> a -> [a] -> [a]
padr = (ap (++) .) . pad

pad :: Int -> a -> [a1] -> [a]
pad = (flip (drop . length) .) . replicate

rgbToHex :: Word8 -> Word8 -> Word8 -> String
rgbToHex r g b = '#' : concatMap (padl 2 '0' . flip showHex "") [r, g, b]

-- temp01's magical function
oOo :: [Char] -> [Char]
oOo [] = []
oOo s  = concat [init s, [toUpper (last s)], tail (reverse s)]

ben :: Integer -> Peen
ben n = '8' : genericReplicate n '=' ++ "D"

type Peen = String

gf :: Integer -> String
gf n | n <  0    = "NEGATIVE U"
     | n == 0    = "N'T U"
     | n <= 9000 = printf "%s U" (unwords $ genericReplicate n "NO")
     | otherwise = "It's over 9000!"

ajpiano :: String
ajpiano = "PANDEMONIUM!!!"

akahn :: Integer -> String
akahn 0 = "akahn :)"
akahn n = printf "AK%sHN!!" (genericReplicate n 'A')

coldhead :: String -> String
coldhead  s | null s    = ">: |"
            | otherwise = printf "these are truly the last %s" s

dytrivedi :: String -> String
dytrivedi s | null s    = "my wife is happy"
            | otherwise = mappend "my wife is annoyed i spend so much time " s

matjas :: Char -> String
matjas = interleave "matjas" . enumFrom

miketaylr :: String -> String
miketaylr s | null ts   = "here, let me open that... wait a minute, there's nothing there, you bitch!"
            | otherwise = unwords ["here, let me open that", ts, "for you!"]
            where ts    = trim s

nimbupani :: String -> String
nimbupani s | null ts   = "HERE LET ME OPEN THAT... WAIT A MINUTE THERES NOTHING THERE U BITCH"
            | otherwise = unwords ["HERE LET ME OPEN THAT", ts, "FOR U"]
            where ts = trim $ map toUpper s

nlogax     :: String -> String
nlogax     = printf "%sn't"

paul_irish :: (effin -> rad) -> effin -> rad
paul_irish = ($)

rwaldron   :: String -> String
rwaldron   = printf "%s. Questions?"

sean       :: String
sean       = "koole"

seutje     :: String -> String
seutje     = printf "I would have %s"

temp01     :: Maybe String
temp01     = Just "awesome"

vladikoff  :: String -> String
vladikoff  = printf "flod %s!!"

mlu :: String
mlu = "much like urself"

muu :: String
muu = "much unlike urself"

source :: String
source = "https://github.com/nlogax/norby"

sauce :: String
sauce = source

trim :: String -> String
trim = let t = reverse . dropWhile isSpace in t . t

dropInit ::  [a] -> [a]
dropInit = drop =<< subtract 1 . length

relTime :: (Integral a, PrintfArg a) => a -> String
relTime n = printTime . take 3 $ omg n times
    where omg _ []        = []
          omg t ((x, s):xs)
              | divs == 0 = rest
              | divs == 1 = (divs, s) : rest
              | otherwise = (divs, s ++ "s") : rest
              where divs = div t x
                    rest = omg (mod t x) xs
          times = [ (31556926, "year")
                  , (2629744,  "month")
                  , (604800,   "week")
                  , (86400,    "day")
                  , (3600,     "hour")
                  , (60,       "minute")
                  , (1,        "second")
                  ] :: Integral a => [(a, String)]

printTime :: (PrintfArg a, PrintfArg b) => [(a, b)] -> String
printTime xs = case xs of
  []                   -> []
  [(n, s)]             -> printf "%d %s" n s
  [(n1, s1), (n2, s2)] -> printf "%d %s and %d %s" n1 s1 n2 s2
  ((n, s):xs')         -> printf "%d %s, %s" n s (printTime xs')

-- Omg postfix function application so you can `car & drive` instead of `drive car`!
infixl 0 &
(&) :: b -> (b -> a) -> a
x & g = g x

ftoc :: Fractional a => a -> a
ftoc t = 5/9 * (t - 32)

ctof :: Fractional a => a -> a
ctof t = (9/5 * t) + 32

f :: Integral a => a -> (b -> String) -> b -> String
f = (.) . (++) . flip genericReplicate 'F' :: (Integral a1) => a1 -> (a -> String) -> a -> String

u :: Integral a => a -> [Char]
u = flip genericReplicate 'U'
