module Regexdo.Format
    (pad,
    Format(..)) where

import Prelude as P
import Regexdo.TypeDo
import Regexdo.Search as S (replace)
import Regexdo.Convert


class Format a where
   format::String -> a -> String


instance Format [String] where
   format = foldr_idx foldFn_idx
-- ^
-- === index based
-- >>> format "на первое {0}, на второе {0}" ["перловка"]
--
-- "на первое перловка, на второе перловка"
--
-- >>> format "Polly {0} a {1}" ["got","cracker"]
--
-- "Polly got a cracker"
--

foldFn_idx::String -> (Int, String) -> String
foldFn_idx v (i,body1) = replaceOne body1 (show i) v


instance Format [(String,String)] where
   format = P.foldr foldFn_map
-- ^
-- === key based
-- key may be {any string}
--
-- >>> format "овчинка {a} не {b}" [("a","выделки"),("b","стоит")]
--
-- "овчинка выделки не стоит"
--

foldFn_map:: (String, String) -> String -> String
foldFn_map (k,v) body1 = replaceOne body1 k v

replaceOne::String -> String -> String -> String
replaceOne body k v = toString bs1
   where pat1 = Needle $ toByteString $ "{" ++ k ++ "}"
         repl1 = Replacement $ toByteString v
         bs1 = S.replace pat1 repl1 $ Haystack $ toByteString body

-- | pad String with Char to total length of Int
--
-- >>> pad '-' 5 "abc"
-- "--abc"
--
pad::Char -> Int -> String -> String
pad c0 tot0 txt0 =
    [const c0 p1 | p1 <- [1..(tot0 - (P.length txt0))]] ++ txt0


--  fold with index
type CustomerFn a b = (a -> (Int,b) -> b)

foldr_idx :: CustomerFn a b -> b -> [a] -> b
foldr_idx fn init1 list = b1
   where i0 = P.length list - 1
         (-1,b1) = P.foldr (foldFn fn) (i0,init1) list

foldFn :: CustomerFn a b -> a -> (Int,b) -> (Int,b)
foldFn fn val t@(i,_)= (i-1,b1)
   where b1 = fn val t