// -*- Mode: C++; tab-width: 2; -*-
// vi: set ts=2:
//

BALL_INLINE 
void File::clear()
{
	File::close();
  name_ = "";
}

BALL_INLINE 
const String& File::getName() const	
{
  return name_;
}

BALL_INLINE 
void File::setName(const String& name)
{
	File::close();
  name_ = name;
  FileSystem::canonizePath(name_);
}


BALL_INLINE 
File::OpenMode File::getOpenMode() const	
{
  return open_mode_;
}
  
BALL_INLINE 
File::Type File::getType(bool trace_link) const
{
  return File::getType(name_, trace_link);
}

BALL_INLINE 
bool File::copyTo(const String& destination_name, Size buffer_size)
{
  return File::copy(name_, destination_name, buffer_size);
}

BALL_INLINE 
bool File::remove(String name)
{
  FileSystem::canonizePath(name);
#ifdef BALL_COMPILER_MSVC
  return (::_unlink(name.c_str()) == 0);
#else
  return (::unlink(name.c_str()) == 0);
#endif
}

BALL_INLINE 
bool File::remove() 
{
#ifdef BALL_COMPILER_MSVC
  File::close();
#endif
  return File::remove(name_);
}

BALL_INLINE 
bool File::move(const String& source_name, const String& destination_name)
{
  if (File::copy(source_name, destination_name))
  {
    return File::remove(source_name);
  }
  return false;
}

BALL_INLINE 
bool File::moveTo(const String& destination_name)
{
#ifdef BALL_COMPILER_MSVC
  File::close();
 #endif
  if (File::move(name_, destination_name))
  {
     name_ = destination_name;
     File::reopen();
     return true;
  }
  return false;
}

BALL_INLINE 
bool File::isAccessible(String name)
{
  FileSystem::canonizePath(name);
#ifdef BALL_COMPILER_MSVC
  return (::_access(name.c_str(),F_OK) == 0);
#else
  return (::access(name.c_str(), F_OK) == 0);
#endif
}

BALL_INLINE 
bool File::isAccessible() const
{
  return File::isAccessible(name_);
}


BALL_INLINE 
bool File::rename(String old_path, String new_path)
{
  FileSystem::canonizePath(old_path);
  FileSystem::canonizePath(new_path);

	if (!isAccessible(old_path))
	{
		throw (Exception::FileNotFound(__FILE__, __LINE__, old_path));
	}
#ifdef BALL_COMPILER_MSVC
  if(old_path==new_path) return true;
#endif


  return (::rename(old_path.c_str(), new_path.c_str()) == 0);

}

BALL_INLINE 
bool File::renameTo(const String& new_path)
{
#ifdef BALL_COMPILER_MSVC
  File::close();
#endif
  if (!File::rename(name_, new_path))
  {
#ifdef BALL_COMPILER_MSVC
        File::reopen();
#endif
		return false;
  }

    name_ = new_path;
#ifdef BALL_COMPILER_MSVC
    File::reopen();
#endif
	return true;
}

BALL_INLINE 
bool File::truncate(String path, Size size)
{
	if (!isAccessible(path))
	{
		throw (Exception::FileNotFound(__FILE__, __LINE__, path));
	}

  FileSystem::canonizePath(path);
  #ifdef BALL_COMPILER_MSVC
	int fh = _open(path.c_str(), _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE );
	int result = _chsize(fh, (long)size);
	_close(fh);
	return (result == 0);
  #else
	return (::truncate(path.c_str(), (long)size) == 0);
  #endif
}

BALL_INLINE 
bool File::truncate(Size size)
{
  return File::truncate(name_, size);
}

BALL_INLINE 
bool File::operator == (const File &file) const	
{
  return (name_ == file.name_);
}

BALL_INLINE 
bool File::operator != (const File &file) const	
{
  return (name_ != file.name_);
}

BALL_INLINE
bool File::isValid() const	
{
  return (getName() != "" && ((File*)this)->std::fstream::good() );
}

BALL_INLINE 
bool File::isOpen()	const	
{
  return is_open_;
}

BALL_INLINE 
bool File::isClosed() const	
{
  return !is_open_;
}

BALL_INLINE 
bool File::isCanonized() const 
{
	if (!isAccessible()) throw(Exception::FileNotFound(__FILE__, __LINE__, name_));

  String canonized_name(name_);

  FileSystem::canonizePath(canonized_name);
  
  return (name_ == canonized_name);
}

BALL_INLINE 
bool File::isReadable(String name)
{
	if (!File::isAccessible(name)) throw(Exception::FileNotFound(__FILE__, __LINE__, name));

  FileSystem::canonizePath(name);
  
  return (::access(name.c_str(), R_OK) == 0);
}

BALL_INLINE 
bool File::isReadable() const 
{
  return File::isReadable(name_);
}

BALL_INLINE 
bool File::isWritable(String name)
{
	if (!File::isAccessible(name)) throw(Exception::FileNotFound(__FILE__, __LINE__, name));

  FileSystem::canonizePath(name);
  
  return (::access(name.c_str(), W_OK) == 0);
}

BALL_INLINE 
bool File::isWritable() const 
{
  return File::isWritable(name_);
}

BALL_INLINE 
bool File::isExecutable(String name)
{
	if (!isAccessible(name)) throw(Exception::FileNotFound(__FILE__, __LINE__, name));

  FileSystem::canonizePath(name);
  #ifdef BALL_COMPILER_MSVC
	return false;
  #else
	return (::access(name.c_str(), X_OK) == 0);
  #endif
}

BALL_INLINE 
bool File::isExecutable() const 
{
  return File::isExecutable(name_);
}

BALL_INLINE 
Size File::getSize(String name)
{
  File tmp(name);
  return tmp.getSize();
}

BALL_INLINE
std::fstream& File::getFileStream()
{
  return *this;
}

BALL_INLINE 
const String& File::getOriginalName()	const	
{
  return original_name_;
}
