--	RegexPR.hs
--
--	Author: Yoshikuni Jujo <PAF01143@nifty.ne.jp>
--

module Text.RegexPR (
  matchRegexPR
, gsubRegexPR
) where

import Hidden.RegexPRCore ( matchRegexPRVerbose )
import Hidden.RegexPRTypes( RegexResult, MatchList )
import Data.Char   ( isDigit )

matchRegexPR :: String -> String -> Maybe ( RegexResult, MatchList )
matchRegexPR reg str
  = fmap ( \( (pre, ret, (_, rest)), ml ) -> ( (ret, (pre, rest)), ml ) ) $
         matchRegexPRVerbose reg ("", str)

subRegexPR :: String -> String -> String -> String
subRegexPR reg sub src
  = case matchRegexPRVerbose reg ("",src) of
         Just all@((pre, ret, sp), ml) -> pre ++ subBackRef all sub ++ snd sp
	 Nothing                       -> src

gsubRegexPR :: String -> String -> String -> String
gsubRegexPR reg sub src = gsubRegexPRGen Nothing reg sub ("", src)

gsubRegexPRGen ::
  Maybe (String, String) -> String -> String -> (String, String) -> String
gsubRegexPRGen pmp reg sub src
  = case matchRegexPRVerbose reg src of
      Just all@((pre, ret, sp@(~(p,x:xs))), ml)
	-> case (pmp, sp) of
		(Just (_, ""), _)  -> ""
		_ | Just sp == pmp -> pre ++ [x] ++
		                      gsubRegexPRGen (Just sp) reg sub (x:p, xs)
		  | otherwise      -> pre ++ subBackRef all sub ++
		                      gsubRegexPRGen (Just sp) reg sub sp
      Nothing -> snd src

subBackRef ::
  ((String, String, (String, String)), MatchList) -> String -> String
subBackRef all@(_, ml) ""     = ""
subBackRef all@(_, ml) ('\\':str)
  = maybe "" id (lookup (read $ takeWhile isDigit str) ml)
    ++ 
    subBackRef all ( case dropWhile isDigit str of
	                  ';':rest -> rest
	                  rest     -> rest )
subBackRef all (c:cs)     = c : subBackRef all cs