{-# LANGUAGE OverloadedStrings #-} module Ham.Cabrillo where import Data.Maybe (isJust, fromJust) import Data.Text as T import Data.Text (unpack) import Data.List as L import Data.Time.Clock import Data.Time.Calendar import Data.Time.LocalTime import Data.Time.Format import Ham.Data data VersionNumber = VersionNumber Int Int instance Show VersionNumber where showsPrec _ (VersionNumber a b) s = L.concat [show a, ".", show b] ++ s data CategoryAssisted = Assisted | NonAssisted instance Show CategoryAssisted where show Assisted = "ASSISTED" show NonAssisted = "NON-ASSISTED" data CategoryMode = CMCW | CMDIGI | CMFM | CMRTTY | CMSSB | CMMIXED instance Show CategoryMode where show CMCW = "CW" show CMDIGI = "DIGI" show CMFM = "FM" show CMRTTY = "RTTY" show CMSSB = "SSB" show CMMIXED = "MIXED" data CategoryOperator = SINGLE_OP | MULTI_OP | CHECKLOG instance Show CategoryOperator where show SINGLE_OP = "SINGLE-OP" show MULTI_OP = "MULTI-OP" show CHECKLOG = "CHECKLOG" data CategoryPower = HIGH | LOW | QRP deriving (Show, Read) data CategoryStation = FIXED | MOBILE | PORTABLE | ROVER | ROVER_LIMITED | ROVER_UNLIMITED | EXPEDITION | HQ | SCHOOL instance Show CategoryStation where show FIXED = "FIXED" show MOBILE = "MOBILE" show PORTABLE = "PORTABLE" show ROVER = "ROVER" show ROVER_LIMITED = "ROVER-LIMITED" show ROVER_UNLIMITED = "ROVER-UNLIMITED" show EXPEDITION = "EXPEDITION" show HQ = "HQ" show SCHOOL = "SCHOOL" data CategoryTime = HOURS_6 | HOURS_12 | HOURS_24 instance Show CategoryTime where show HOURS_6 = "6-HOURS" show HOURS_12 = "12-HOURS" show HOURS_24 = "24-HOURS" data CategoryTransmitter = ONE | TWO | LIMITED | UNLIMITED | SWL deriving (Show, Read) data CategoryOverlay = CLASSIC | ROOKIE | TB_WIRES | NOVICE_TECH | OVER_50 instance Show CategoryOverlay where show CLASSIC = "CLASSIC" show ROOKIE = "ROOKIE" show TB_WIRES = "TB-WIRES" show NOVICE_TECH = "NOVICE-TECH" show OVER_50 = "OVER-50" data YesNo = YES | NO deriving (Show, Read) data Cabrillo = Cabrillo { version :: VersionNumber , callsign :: Maybe Text , contest :: Maybe Text , category_assisted :: Maybe CategoryAssisted , category_band :: Maybe Text , category_mode :: Maybe CategoryMode , category_operator :: Maybe CategoryOperator , category_power :: Maybe CategoryPower , category_station :: Maybe CategoryStation , category_time :: Maybe CategoryTime , category_transmitter :: Maybe CategoryTransmitter , category_overlay :: Maybe CategoryOverlay , certificate :: Maybe YesNo , claimed_score :: Maybe Integer , club :: Maybe Text , created_by :: Maybe Text , email :: Maybe Text , grid_locator :: Maybe Text , location :: Maybe Text -- Note: This is restricted depending on the contest. See http://wwrof.org/cabrillo/cabrillo-specification-v3/ , name :: Maybe Text , address_city :: Maybe Text , address_state_province :: Maybe Text , address_postalcode :: Maybe Text , address_country :: Maybe Text , operators :: Maybe [Text] } defaultCabrillo = Cabrillo (VersionNumber 3 0) Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing showtext d f a = fmap (\b -> L.concat [a, unpack b]) $ f d showother d f a = fmap (\b -> L.concat [a, show b]) $ f d showlist :: d -> (d -> Maybe [Text]) -> String -> Maybe String showlist d f a = fmap (\b -> a ++ L.unwords (L.map unpack b)) $ f d instance Show Cabrillo where show c = L.unlines $ L.map fromJust $ L.filter isJust [ showtext c callsign "CALLSIGN: " ,showtext c contest "CONTEST: " ,showother c category_assisted "CATEGORY-ASSISTED: " ,showtext c category_band "CATEGORY-BAND: " ,showother c category_mode "CATEGORY-MODE: " ,showother c category_operator "CATEGORY-OPERATOR: " ,showother c category_power "CATEGORY-POWER: " ,showother c category_station "CATEGORY-STATION: " ,showother c category_time "CATEGORY-TIME: " ,showother c category_transmitter "CATEGORY-TRANSMITTER: " ,showother c category_overlay "CATEGORY-OVERLAY: " ,showother c certificate "CERTIFICATE: " ,showother c claimed_score "CLAIMED-SCORE: " ,showtext c club "CLUB: " ,showtext c created_by "CREATED-BY: " ,showtext c email "EMAIL: " ,showtext c grid_locator "GRID-LOCATOR: " ,showtext c location "LOCATION: " ,showtext c name "NAME: " ,showtext c address_city "ADDRESS-CITY: " ,showtext c address_state_province "ADDRESS-STATE-PROVINCE: " ,showtext c address_postalcode "ADDRESS-POSTALCODE: " ,showtext c address_country "ADDRESS-COUNTRY: " ,showlist c operators "OPERATORS: "] data CabrilloLine = CLSoapbox Text | CLQso CabrilloQso | CLX Text Text | CLXQso CabrilloQso instance Show CabrilloLine where show (CLSoapbox t) = "SOAPBOX: " ++ unpack t show (CLQso a) = "QSO: " ++ show a show (CLX a b) = "X-" ++ unpack a ++ ": " ++ unpack b show (CLXQso a) = "X-QSO: " ++ show a -- Note: OffTime is missing. data CabrilloQso = CabrilloQso Frequency Mode UTCTime CabrilloInfoSent CabrilloInfoReceived (Maybe TransmitterNumber) data CabrilloInfo = CabrilloInfo Callsign Exchange instance Show CabrilloInfo where show (CabrilloInfo cs exchg) = L.unwords [cs, exchg] type Exchange = String type Callsign = String type Location = String type CabrilloInfoSent = CabrilloInfo type CabrilloInfoReceived = CabrilloInfo type TransmitterNumber = Int data Mode = CW | PH | FM | RY | DG deriving (Show, Read) instance Show CabrilloQso where show (CabrilloQso (MHz f) m t s r mn) = L.unwords $ [ show $ round (f * 1000) ,show m ,date ,tm ,show s ,show r ,maybe [] show mn ] where date = formatTime defaultTimeLocale "%F" t tm = formatTime defaultTimeLocale "%H%M" t data CabrilloLog = CabrilloLog Cabrillo [CabrilloLine] instance Show CabrilloLog where show (CabrilloLog c ls) = L.unlines $ [ "START-OF-LOG: 3.0" ,show c ,L.unlines (L.map show ls) ,"END-OF-LOG:"] class ToCabrillo a where toCabrillo :: a -> [CabrilloLine]