# -*- coding: utf-8 -*-
#
#	Copyright (C) 2003-2011 by Igor E. Novikov
#	
#	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 3 of the License, 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.  If not, see <http://www.gnu.org/licenses/>.

#
#	File system related functions used in various places...
#

import os
import sys
import system

#Return directory list for provided path

def get_dirs(path='.'):
	list = []
	if path:
		if os.path.isdir(path):
			try:
				names = os.listdir(path)
			except os.error:
				return []
		names.sort()
		for name in names:
			if os.path.isdir(os.path.join(path, name)):
				list.append(name)
		return list

def get_dirs_withpath(path='.'):
	list = []
	names = []
	if os.path.isdir(path):
		try:
			names = os.listdir(path)
		except os.error:
			return names
	names.sort()
	for name in names:
		if os.path.isdir(os.path.join(path, name)) and not name == '.svn':
			list.append(os.path.join(path, name))
	return list

#Return file list for provided path
def get_files(path='.', ext='*'):
	list = []
	if path:
		if os.path.isdir(path):
			try:
				names = os.listdir(path)
			except os.error:
				return []
		names.sort()
		for name in names:
			if not os.path.isdir(os.path.join(path, name)):
				if ext == '*':
					list.append(name)
				elif '.' + ext == name[-1 * (len(ext) + 1):]:
					list.append(name)
	return list

#Return full file names list for provided path
def get_files_withpath(path='.', ext='*'):
	import glob
	if ext:
		if ext == '*':
			list = glob.glob(os.path.join(path, "*." + ext))
			list += glob.glob(os.path.join(path, "*"))
			list += glob.glob(os.path.join(path, ".*"))
		else:
			list = glob.glob(os.path.join(path, "*." + ext))
	else:
		list = glob.glob(os.path.join(path, "*"))
	list.sort()
	result = []
	for file in list:
		if os.path.isfile(file):
			result.append(file)
	return result

#Return recursive directories list for provided path
def get_dirs_tree(path='.'):
	tree = get_dirs_withpath(path)
	res = [] + tree
	for node in tree:
		subtree = get_dirs_tree(node)
		res += subtree
	return res

#Return recursive files list for provided path
def get_files_tree(path='.', ext='*'):
	tree = []
	dirs = [path, ]
	dirs += get_dirs_tree(path)
	for dir in dirs:
		list = get_files_withpath(dir, ext)
		list.sort()
		tree += list
	return tree

#
#	Filename manipulation
#

def find_in_path(paths, file):
	"""
	The function finds a file FILE in one of the directories listed in PATHS. If a file
	is found, return its full name, None otherwise.
	"""
	for path in paths:
		fullname = os.path.join(path, file)
		if os.path.isfile(fullname):
			return fullname


def find_files_in_path(paths, files):
	"""
	The function finds one of the files listed in FILES in one of the directories in
	PATHS. Return the name of the first one found, None if no file is
	found.
	"""
	for path in paths:
		for file in files:
			fullname = os.path.join(path, file)
			if os.path.isfile(fullname):
				return fullname

def xclear_dir(path):
	"""
	Remove recursively all files and subdirectories from path.
	path directory is not removed. 
	"""
	files = get_files_tree(path)
	for file in files:
		if os.path.lexists(file):
			os.remove(file)

	dirs = get_dirs_tree(path)
	for dir in dirs:
		if os.path.lexists(dir):
			os.rmdir(dir)

def xremove_dir(path):
	"""
	Remove recursively all files and subdirectories from path
	including path directory. 
	"""
	xclear_dir(path)
	os.removedirs(path)

def expanduser_unicode(path):
	"""
	Fixes expanduser functionality for non-unicode platforms.
	"""
	path = os.path.expanduser(path.encode(sys.getfilesystemencoding()))
	return path.decode(sys.getfilesystemencoding())

def path_unicode(path):
	return path.decode(sys.getfilesystemencoding())

def path_system(path):
	return path.encode(sys.getfilesystemencoding())

def get_system_fontdirs():
	"""
	The function detects system font directories according to detected 
	system type.
	"""
	if system.get_os_family() == system.LINUX:
		home = os.path.expanduser('~')
		return ['/usr/share/fonts', os.path.join(home, '.fonts')]
	if  system.get_os_family() == system.WINDOWS:
		try:
			import _winreg
		except ImportError:
			return [os.path.join(os.environ['WINDIR'], 'Fonts'), ]
		else:
			k = _winreg.OpenKey(
				_winreg.HKEY_CURRENT_USER,
				r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
			)
			try:
				return [_winreg.QueryValueEx(k, "Fonts")[0], ]
			finally:
				_winreg.CloseKey(k)
	if system.get_os_family() == system.MACOSX:
		#FIXME: It's a stub. The paths should be more exact.
		return ['/', ]


DIRECTORY_OBJECT = 0
FILE_OBJECT = 1
UNKNOWN_OBJECT = 2

REGULAR_OBJECT = 0
LINK_OBJECT = 1

class FileObject:
	"""
	The class represents file system object in UNIX-like style ('all are files').
	"""
	type = FILE_OBJECT
	is_link = REGULAR_OBJECT
	is_hidden = 0
	ext = ''
	name = ''
	basename = ''

	def __init__(self, path):
		self.path = path
		if os.path.isdir(self.path):
			self.type = DIRECTORY_OBJECT
		elif os.path.isfile(self.path):
			self.type = FILE_OBJECT
		else:
			self.type = UNKNOWN_OBJECT

		if os.path.islink(self.path):
			self.is_link = LINK_OBJECT

		self.basename = os.path.basename(self.path)

		if not system.get_os_family() == system.WINDOWS:
			if self.basename[0] == '.':
				self.is_hidden = 1

		if self.type:
			if self.is_hidden:
				self.ext = os.path.splitext(self.basename[1:])[1][1:]
				self.name = os.path.splitext(self.basename[1:])[0]
			else:
				self.ext = os.path.splitext(self.basename)[1][1:]
				self.name = os.path.splitext(self.basename)[0]
		else:
			self.name = os.path.basename(self.path)


def get_file_objs(path):
	"""
	Scans provided path for directories and files.
	On success returns a list of file objects.
	On error returns None.
	"""
	if path[0] == '~':
		path = os.path.expanduser(path)
	if os.path.exists(path) and os.path.isdir(path):
		objs = []
		try:
			paths = os.listdir(path)
		except os.error:
			return None
		paths.sort()
		for item in paths:
			objs.append(FileObject(os.path.join(path, item)))
		result = []
		for obj in objs:
			if not obj.type: result.append(obj)
		for obj in objs:
			if obj.type: result.append(obj)
		return result
	return None

def get_file_extension(path):
	"""
	Returns file extension without comma.
	"""
	ext = os.path.splitext(path)[1]
	ext = ext.lower().replace('.', '')
	return ext

def change_file_extension(path, ext):
	filename = os.path.splitext(path)[0]
	ext = ext.lower().replace('.', '')
	return filename + '.' + ext




def _test():
	files = get_file_objs("~")
	if files is None:
		print 'ERROR!'
	else:
		for file in files:
			if not file.is_hidden:
				print file.basename


if __name__ == '__main__':
    _test()


