module AdvSearch.RDate exposing (..) import Html exposing (..) import Html.Attributes exposing (..) import Lib.Html exposing (..) import Lib.RDate as R import AdvSearch.Lib exposing (..) type alias Model = { op : Op , fuzzy : Bool , date : R.RDate } type Msg = MOp Op | Fuzzy Bool | Date R.RDate onlyEq : Int -> Bool onlyEq d = d == 99999999 || d == 0 update : Msg -> Model -> Model update msg model = case msg of MOp o -> { model | op = o } Fuzzy f -> { model | fuzzy = f } Date d -> { model | op = if onlyEq d && model.op /= Eq && model.op /= Ne then Eq else model.op, date = d } init : Data -> (Data, Model) init dat = (dat, { op = Le , fuzzy = True , date = 1 }) toQuery : Model -> Maybe Query toQuery model = Just <| let f o date = QInt 7 o date e = R.expand model.date ystart = R.compact { y=e.y, m= 1, d= 1 } mstart = R.compact { y=e.y, m=e.m, d= 1 } in if not model.fuzzy || e.y == 0 || e.y == 9999 then f model.op model.date else case (model.op, e.m, e.d) of -- Fuzzy (in)equality turns into a date range (Eq, 99, 99) -> QAnd [ f Ge ystart, f Le model.date ] (Eq, _, 99) -> QAnd [ f Ge mstart, f Le model.date ] (Ne, 99, 99) -> QOr [ f Lt ystart, f Gt model.date ] (Ne, _, 99) -> QOr [ f Lt mstart, f Gt model.date ] -- Fuzzy Ge and Lt just need the date adjusted to the correct boundary (Ge, 99, 99) -> f Ge ystart (Ge, _, 99) -> f Ge mstart (Lt, 99, 99) -> f Lt ystart (Lt, _, 99) -> f Lt mstart _ -> f model.op model.date fromQuery : Data -> Query -> Maybe (Data, Model) fromQuery dat q = let m op fuzzy date = Just (dat, { op = op, fuzzy = fuzzy, date = date }) fuzzyNeq op start end = let se = R.expand start ee = R.expand end in if se.y == ee.y && (ee.m < 99 || se.m == 1) && se.d == 1 && ee.d == 99 then m op True end else Nothing canFuzzy o e = e.y == 0 || e.y == 9999 || e.d /= 99 || o == Gt || o == Le in case q of QAnd [QInt 7 Ge start, QInt 7 Le end] -> fuzzyNeq Eq start end QOr [QInt 7 Lt start, QInt 7 Gt end] -> fuzzyNeq Ne start end QInt 7 o v -> m o (canFuzzy o (R.expand v)) v _ -> Nothing view : Model -> (Html Msg, () -> List (Html Msg)) view model = ( text <| showOp model.op ++ " " ++ R.format (R.expand model.date) , \() -> [ div [ class "advheader", style "width" "290px" ] [ h3 [] [ text "Release date" ] , div [ class "opts" ] [ inputOp (onlyEq model.date) model.op MOp , if (R.expand model.date).d /= 99 || model.date == 99999999 then text "" else linkRadio model.fuzzy Fuzzy [ span [ title <| "Without fuzzy matching, partial dates will always match after the last date of the chosen time period, " ++ "e.g. \"< 2010-10\" would also match anything released in 2010-10 and \"= 2010-10\" would only match releases for which we don't know the exact date." ++ "\n\nFuzzy match will adjust the query to do what you mean." ] [ text "fuzzy" ] ] ] ] , R.view model.date True True Date ] )