%  Copyright (C) 2002-2003,2008 David Roundy
%
%  This program is free software; you can redistribute it and/or modify
%  it under the terms of the GNU General Public License as published by
%  the Free Software Foundation; either version 2, or (at your option)
%  any later version.
%
%  This program is distributed in the hope that it will be useful,
%  but WITHOUT ANY WARRANTY; without even the implied warranty of
%  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%  GNU General Public License for more details.
%
%  You should have received a copy of the GNU General Public License
%  along with this program; see the file COPYING.  If not, write to
%  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
%  Boston, MA 02110-1301, USA.


THIS MODULE IS DEPRECATED.  DON'T USE IT FOR ANYTHING NEW, AND REMOVE
CODE FROM IT WHEN POSSIBLE!

\begin{code}
module UglyFileName ( fp2fn, fn2fp,
                      norm_path, own_name, super_name,
                      patch_filename,
                      breakup, is_explicitly_relative,
                    ) where

-- THIS MODULE IS DEPRECATED.  DON'T USE IT FOR ANYTHING NEW, AND
-- REMOVE CODE FROM IT WHEN POSSIBLE! WE'D LIKE TO REMOVE IT SOON...

import System.IO
import Data.Char ( isAlpha, isSpace, isDigit, toLower )
\end{code}

\begin{code}
newtype FileName = FN FilePath deriving ( Eq, Ord )

instance Show FileName where
   showsPrec d (FN fp) = showParen (d > app_prec) $ showString "fp2fn " . showsPrec (app_prec + 1) fp
      where app_prec = 10

{-# INLINE fp2fn #-}
fp2fn :: FilePath -> FileName
fp2fn fp = FN fp

{-# INLINE fn2fp #-}
fn2fp :: FileName -> FilePath
fn2fp (FN fp) = fp
\end{code}

\begin{code}
own_name :: FileName -> FileName
own_name (FN f) = case breakLast '/' f of Nothing -> FN f
                                          Just (_,f') -> FN f'
super_name :: FileName -> FileName
super_name fn = case norm_path fn of
                FN f -> case breakLast '/' f of
                        Nothing -> FN "."
                        Just ("",_) -> FN "/"
                        Just (d ,_) -> FN d

norm_path :: FileName -> FileName -- remove "./"
norm_path (FN p) = FN $ repath $ drop_dotdot $ breakup p

repath :: [String] -> String
repath [] = ""
repath [f] = f
repath (d:p) = d ++ "/" ++ repath p

drop_dotdot :: [String] -> [String]
drop_dotdot [] = []
drop_dotdot f@(a:b)
    | null a = "" : (drop_dotdot' b) -- first empty element is important
                                     -- for absolute paths
    | otherwise = drop_dotdot' f
    where drop_dotdot' ("":p) = drop_dotdot' p
          drop_dotdot' (".":p) = drop_dotdot' p
          drop_dotdot' ("..":p) = ".." : (drop_dotdot' p)
          drop_dotdot' (_:"..":p) = drop_dotdot' p
          drop_dotdot' (d:p) = case drop_dotdot' p of
                                 ("..":p') -> p'
                                 p' -> d : p'
          drop_dotdot' [] = []

breakup :: String -> [String]
breakup p = case break (=='/') p of
            (d,"") -> [d]
            (d,p') -> d : breakup (tail p')

breakFirst :: Char -> String -> Maybe (String,String)
breakFirst c l = bf [] l
    where bf a (r:rs) | r == c = Just (reverse a,rs)
                      | otherwise = bf (r:a) rs
          bf _ [] = Nothing
breakLast :: Char -> String -> Maybe (String,String)
breakLast c l = case breakFirst c (reverse l) of
                Nothing -> Nothing
                Just (a,b) -> Just (reverse b, reverse a)

safeFileChar :: Char -> Char
safeFileChar c | isAlpha c = toLower c
               | isDigit c = c
               | isSpace c = '-'
safeFileChar _ = '_'

patch_filename :: String -> String
patch_filename summary = name ++ ".dpatch"
    where name = map safeFileChar summary

\end{code}

\begin{code}
is_explicitly_relative :: String -> Bool
is_explicitly_relative ('.':'/':_) = True  -- begins with "./"
is_explicitly_relative _ = False
\end{code}
