#
# UnixDirectoryClient.rb
#
#   $Author: hiroya $
#   $Date: 2000/11/23 01:53:10 $
#   Copyright (C) 2000 Hiroya KUBO
#

class NamingException < Exception
  def initialize(value = "")
    @value = value
  end
  
  def getValue
    return @value
  end
end

module UnixPathName
  CURRENTPATH = '.'
  PARENTPATH = '..'

  def getSeparator
    return File::Separator
  end

  def getRoot
    return File::Separator
  end

  def directory?(dir)
    if(dir == nil || dir == "")
      return true
    end
    return FileTest.directory?(dir)
  end

  def absolute?(name)
    if(name == nil || name == "")
      return false
    else
      return name.index(getSeparator) == 0
    end
  end

  def dirname(name)
    if((p = name.rindex(getSeparator)) > 0)
      return name[0..p-1]
    else
      return getSeparator
    end
  end

  def basename(name)
    if(0 <= (p = name.rindex(getSeparator)) && p < name.size)
      return name[p+1..name.size]
    else
      return ""
    end
  end

  def addname(dir, base)
    if(dir =~/\/$/)
      return dir + base
    else
      return dir + getSeparator + base
    end
  end

  def getRegulatedName(name)
    regulated_name = []
    top = -1
    for n in name.split(getSeparator, -1)
      top += 1
      if( n == nil || n == "." || (top != 0 && n == ""))
	next
      elsif(n == "..")
	if (regulated_name.length > 1)
	  regulated_name.pop
	else
	  regulated_name.push('')
	end
      else
	regulated_name.push(n)
      end
    end

    ret = regulated_name.join(getSeparator)
    if (ret == "")
      return getSeparator
    else
      return ret
    end
  end
end

class UnixDirectoryClient
  include UnixPathName

  def initialize(name = Dir.pwd)
    @pwd = name
  end

  def setPath?(path)
    if (! FileTest.exist? (path) )
      raise NamingException.new(path+": No such file or directory.")
    elsif (! FileTest.directory? (path) )
      raise NamingException.new(path+": Not a directory.")
    elsif (! FileTest.readable?(path) ||
	   ! FileTest.executable?(path))
      raise NamingException.new(path+": Permission denied.")
    end
    return true
  end

  def getContextualName(name)
    if (absolute?(name)) then
      return name
    else
      return addname(@pwd, name)
    end
  end

  def foreach(basedir, &block)
    begin
      if(! setPath?(basedir))
	return
      end
    rescue NamingException
      return
    end

    dir = Dir.open(basedir)
    begin
      while(filename = dir.read)
	if(filename != ".." && filename != ".")
	  yield(filename)
	end
      end
    ensure
      dir.close
    end
  end

  def getHomeDirectory
    return ENV["HOME"]
  end

  def setPath(name)
    path = getRegulatedName(getContextualName(name))
    setPath?(path)
    @pwd = path
    Dir.chdir(path)
  end

  def getPath
    # Dir.pwd
    return @pwd
  end

end
