{-# LANGUAGE OverloadedStrings, TemplateHaskell #-}
module Ham.Internal.Data where
import Data.Aeson
import Data.Aeson.TH
import Data.List
import Data.Char (isDigit, digitToInt)
newtype Frequency = MHz Float
deriving (Show, Read, Eq, Ord)
wavelength :: Frequency -> Float
wavelength (MHz f) = c / (f * 1e6)
where c = 299792458
bands = [160, 80, 60, 40, 30, 20, 17, 15, 12, 10, 6, 2, 1.25, 0.7, 0.33, 0.23]
band_name :: Float -> String
band_name a | (fromIntegral $ round a) == a = show (round a) <> "m"
| a > 1.0 = show a <> "m"
| otherwise = show (round $ a * 100) <> "cm"
data Band = M Float
| Microwave
deriving Eq
instance Show Band where
show (M b) = band_name b
show Microwave = "Microwave"
band :: Frequency -> Band
band f = case m of
(0.23, d) -> if (d / 0.23) > 0.15 then Microwave else M 0.23
(a, _) -> M a
where l = wavelength f
diffs = map (\a -> (a, abs (l - a))) bands
m = minimumBy (\a b -> compare (snd a) (snd b)) diffs
data QsoMode = CW
| PH
| FM
| RY
| DATA
deriving (Show, Read, Eq)
data RST = RST Int Int Int
| RS Int Int
| NoRST deriving (Eq, Ord)
rstReadability :: RST -> Int
rstReadability (RST r _ _) = r
rstReadability (RS r _) = r
rstReadability _ = 0
rstStrength :: RST -> Int
rstStrength (RST _ s _) = s
rstStrength (RS _ s) = s
rstStrength _ = 0
rstTone :: RST -> Int
rstTone (RST _ _ t) = t
rstTone (RS _ _) = 0
rstTone _ = 0
instance Show RST where
show (RST r s t) = show r ++ show s ++ show t
show (RS r s) = show r ++ show s
show _ = ""
instance Read RST where
readsPrec _ ss@(r:s:t:rest) = if Data.List.all isDigit (r:s:t:[]) then
[(RST (digitToInt r) (digitToInt s) (digitToInt t), rest)] else
[(NoRST, ss)]
readsPrec _ ss@(r:s:rest) = if Data.List.all isDigit (r:s:[]) then
[(RS (digitToInt r) (digitToInt s), rest)] else
[(NoRST, ss)]
readsPrec _ ss = [(NoRST, ss)]
$(deriveJSON defaultOptions ''Frequency)
$(deriveJSON defaultOptions ''RST)
$(deriveJSON defaultOptions ''QsoMode)