"""
     qtgui/mg2.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2011 University of York

     This library is free software: you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public License
     version 3, modified in accordance with the provisions of the 
     license to address the requirements of UK law.
 
     You should have received a copy of the modified GNU Lesser General 
     Public License along with this library.  If not, copies may be 
     downloaded from http://www.ccp4.ac.uk/ccp4license.php
 
     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 Lesser General Public License for more details.
"""
import sys,os
import shutil
import copy


def getCCP4MG_DIR():
	#target = os.path.join(os.path.realpath(sys.argv[0]),"..")
	target = os.path.join(__file__,"..")
	abstarget = os.path.abspath(target)
	targetdir = os.path.dirname(abstarget)
	return targetdir
	
def setup_pythonpath():
	CCP4MG = getCCP4MG_DIR()
	sys.path.append(CCP4MG)
	sys.path.append(os.path.join(CCP4MG,"util"))
	sys.path.append(os.path.join(CCP4MG,"pygl"))
	sys.path.append(os.path.join(CCP4MG,"mgapp"))
	sys.path.append(os.path.join(CCP4MG,"mmut"))
	sys.path.append(os.path.join(CCP4MG,"mmdb","src"))
	sys.path.append(os.path.join(CCP4MG,"surface"))
	sys.path.append(os.path.join(CCP4MG,"python","ui"))
	sys.path.append(os.path.join(CCP4MG,"lib"))

def setup_environment():
	targetdir = getCCP4MG_DIR()
	CCP4MG = targetdir
	CCP4_MGDATA=os.path.join(CCP4MG,"data")
	if sys.platform == "linux2":
	        PYTHONHOME=os.path.join(CCP4MG,"pythondist")
	        os.environ["PYTHONHOME"] = PYTHONHOME
	if sys.platform == "darwin":
		PYTHONHOME=os.path.join(CCP4MG,"Frameworks/Python.framework/Versions/Current")
		DYLD_FRAMEWORK_PATH=os.path.join(CCP4MG,"Frameworks")
		os.environ["DYLD_FRAMEWORK_PATH"] = DYLD_FRAMEWORK_PATH
	        os.environ["PYTHONHOME"] = PYTHONHOME

	
	#CLIBD=os.path.join(CCP4MG,"ccp4_suite","lib","data")
        if os.path.exists(os.path.join(sys.prefix,"..","CCP4")):
          # The case where we are installed in site-packages of a pythondist in $CCP4MG. And CCP4 stuff has been copied.
	  CCP4=os.path.join(sys.prefix,"..","CCP4")
	  os.environ["CCP4"] = CCP4
        elif os.path.exists(os.path.join(CCP4MG,"CCP4")):
          # The case where we are running qtgui/mg2.py in build directory and CCP4 stuff has been copied. Probably should not ever.
	  CCP4=os.path.join(CCP4MG,"CCP4")
	  os.environ["CCP4"] = CCP4
        elif os.environ.has_key("CCP4"):
	  CCP4=os.environ["CCP4"]
        else:
          print "No CCP4 environment variable or CCP4 folder in CCP4MG folder";
          sys.exit()
        print "Using",CCP4
	CLIBD=os.path.join(CCP4,"lib","data")
	MONOMER_LIBRARY=os.path.join(CCP4,"lib","data","monomers")
	if os.path.isfile(os.path.join(CCP4,"share","ccp4","syminfo.lib")):
		SYMINFO=os.path.join(CCP4,"share","ccp4","syminfo.lib")
	if os.path.isfile(os.path.join(CCP4,"lib","data","syminfo.lib")):
		SYMINFO=os.path.join(CCP4,"lib","data","syminfo.lib")
	PROSMART_DIR=os.path.join(CCP4,"bin")
	MG_PISA_DIR=os.path.join(CCP4,"bin")
	os.environ["CLIBD"] = CLIBD
	os.environ["SYMINFO"] = SYMINFO
	os.environ["PROSMART_DIR"] = PROSMART_DIR
	os.environ["MG_PISA_DIR"] = MG_PISA_DIR
	os.environ["MONOMER_LIBRARY"] = MONOMER_LIBRARY
	
	if sys.platform == "win32":
		path_sep = ';'
	else:
		path_sep = ':'
	DYLD_LIBRARY_PATH=CCP4MG + path_sep + \
		os.path.join(CCP4MG,"util") + path_sep + \
		os.path.join(CCP4MG,"pygl") + path_sep + \
		os.path.join(CCP4MG,"mgapp") + path_sep + \
		os.path.join(CCP4MG,"mmut") + path_sep + \
		os.path.join(CCP4MG,"mmdb","src") + path_sep + \
		os.path.join(CCP4MG,"surface") + path_sep + \
		os.path.join(CCP4MG,"lib")
	if sys.platform == "darwin":
		PYTHONPATH=CCP4MG + path_sep + \
		os.path.join(CCP4MG,"util") + path_sep + \
		os.path.join(CCP4MG,"pygl") + path_sep + \
		os.path.join(CCP4MG,"mgapp") + path_sep + \
		os.path.join(CCP4MG,"mmut") + path_sep + \
		os.path.join(CCP4MG,"mmdb","src") + path_sep + \
		os.path.join(CCP4MG,"surface") + path_sep + \
		os.path.join(CCP4MG,"python","ui") + path_sep + \
		os.path.join(CCP4MG,"lib")
		os.environ["PYTHONPATH"] = PYTHONPATH

	if os.path.exists(os.path.join(CCP4MG,"imagemagick","bin","convert")):
		os.environ["MAGICK_HOME"] = os.path.join(CCP4MG,"imagemagick")
		DYLD_LIBRARY_PATH= os.path.join(CCP4MG,"imagemagick","lib")+ path_sep + DYLD_LIBRARY_PATH
		os.environ["PATH"] = os.path.join(CCP4MG,"imagemagick","bin") + path_sep + os.environ["PATH"]
	if os.path.exists(os.path.join(CCP4MG,"imagemagick","convert.exe")):
		sys.stdout.flush()

	os.environ["DYLD_FALLBACK_LIBRARY_PATH"] = DYLD_LIBRARY_PATH
	os.environ["LD_LIBRARY_PATH"] = DYLD_LIBRARY_PATH
	os.environ["LIBPATH"] = DYLD_LIBRARY_PATH
	if sys.platform == "win32":
		OLDPATH=os.environ["PATH"]
		PATH=os.path.join(CCP4,"bin") + path_sep + os.path.join(CCP4MG,"bin") + path_sep + os.path.join(CCP4MG,"lib") + path_sep + os.path.join(CCP4MG,"pythondist") + path_sep + os.path.join(CCP4,"lib") + path_sep + os.path.join(CCP4MG,"ffmpeg","bin") + path_sep + os.path.join(CCP4MG,"imagemagick") + path_sep + DYLD_LIBRARY_PATH + path_sep + OLDPATH
		os.environ["PATH"] = PATH
		os.environ["PYTHONPATH"] = PATH
		if not os.environ.has_key("HOME") or os.environ["HOME"] == "":
			try:
				HOME=os.environ["USERPROFILE"]
				os.environ["HOME"] = HOME
			except:
				pass
	else:
		os.environ["PATH"] = os.path.join(CCP4MG,"bin") + path_sep + os.environ["PATH"]
	
	os.environ["CCP4MG"] = CCP4MG
	os.environ["CCP4_MGDATA"] = CCP4_MGDATA
	os.environ["MONOMER_LIBRARY"] = MONOMER_LIBRARY
	if not os.environ.has_key("CLIBD"):
          os.environ["CLIBD"] = CLIBD
	os.environ["CCP4MG_CIRCLE_TEXTURE_FILE"] = os.path.join(CCP4MG,'qticons','circles.png')

def visit(topdir,dirname,names):
	dest = topdir[0]
	try:
		dest = os.path.join(topdir[0],dirname[len(topdir[1])+1:])
	except:
		print "Problem patching"
		return
	for name in names:
		fname = os.path.join(dirname,name)
		fdest = os.path.join(dest,name)
		if os.path.isdir(fname):
			try:
				if not os.path.isdir(fdest):
					print 'Make directory',fdest; sys.stdout.flush()
					os.makedirs(fdest)
			except:
				sys.stderr.write("Could not create directory "+fdest)
				exc_type, exc_value,exc_tb = sys.exc_info()[:3]
				sys.stderr.write(exc_type)
				sys.stderr.write(exc_value)
		else:
			try:
				print "Copy",fname,'to',fdest; sys.stdout.flush()
				shutil.copy(fname,fdest)
			except:
				sys.stderr.write("Could not create file "+fdest)
				exc_type, exc_value,exc_tb = sys.exc_info()[:3]
				sys.stderr.write(exc_type)
				sys.stderr.write(exc_value)

def apply_update(version,directory):
	sys.stdout.flush()
	topdirectory = os.path.abspath(os.path.join(directory,'..'))
	print "Apply version",version,'to',topdirectory
	directory = os.path.join(directory,version)
	sys.stdout.flush()
	os.path.walk(directory,visit,[topdirectory,directory])
	

def check_for_updates(directory):
	versionfile = os.path.join(directory,"python","ui","version.py")
	version_py = open(versionfile,"r")
	version = version_py.read()
	version_py.close()
	exec version 
	current_version = ccp4mg_version
	print "Current",current_version
	directory = os.path.join(directory,"autoupdate")
	if os.path.isdir(directory):

		files = os.listdir(directory)
		newest_major_version=0
		newest_minor_version=0
		newest_patch_version=0
		newest_version = '0.0.0'
		if len(files) == 0 : return (None, None)
		try:
			for dirfile in files:
				version_no = dirfile.split('.')
				this_major_version = int(version_no[0])
				this_minor_version = int(version_no[1])
				this_patch_version = int(version_no[2])
				if  this_major_version > newest_major_version:
					newest_major_version=this_major_version
					newest_minor_version=this_minor_version
					newest_patch_version=this_patch_version
					newest_version = dirfile
				elif  this_major_version == newest_major_version:
					if  this_minor_version > newest_minor_version:
						newest_major_version=this_major_version
						newest_minor_version=this_minor_version
						newest_patch_version=this_patch_version
						newest_version = dirfile
					elif  this_minor_version == newest_minor_version:
						if  this_patch_version > newest_patch_version:
								newest_major_version=this_major_version
								newest_minor_version=this_minor_version
								newest_patch_version=this_patch_version
								newest_version = dirfile
						else:
								return (None, None)
			newest_major_version = int(newest_major_version)
			newest_minor_version = int(newest_minor_version)
			newest_patch_version = int(newest_patch_version)
			current_major_version = int(current_version.split('.')[0])
			current_minor_version = int(current_version.split('.')[1])
			current_patch_version = int(current_version.split('.')[2])

			if newest_major_version > current_major_version:
				print "New major version"
				return (newest_version,directory)
			elif newest_major_version == current_major_version:
				if newest_minor_version > current_minor_version:
					print "New minor version"
					return (newest_version,directory)
				elif newest_minor_version == current_minor_version:
					if newest_patch_version > current_patch_version:
						print "New patch version"
						return (newest_version,directory)
		except:
			return (None, None)
	else:	
		pass

	return (None, None)

def runmg():
	import socket
	setup_environment()
	ccp4mg = getCCP4MG_DIR()
	#print sys.argv; sys.stdout.flush()
	if sys.platform == "win32":
                env = copy.deepcopy(os.environ)
                env["PYTHONHOME"]=sys.prefix
		#mainpy = os.path.join("qtgui","main.py")
                mainpy = os.path.join(env["CCP4MG"],"qtgui","main.py")
		import subprocess
		retval = 128
		args = ["python",mainpy]
		for sysarg in sys.argv[1:]:
			args.append(sysarg)
		#print args; sys.stdout.flush()
		while retval == 128:
			print "Checking for updates"; sys.stdout.flush()
			newest_version,directory = check_for_updates(ccp4mg)
			print newest_version,directory
			if newest_version and directory:
				if sys.platform == "win32":
					import ctypes
					isanadmin = ctypes.windll.shell32.IsUserAnAdmin()
					if isanadmin:
						apply_update(newest_version,directory)
					else:
						sys.path.append(os.path.normpath(os.path.join(os.environ["CCP4MG"],"util")))
						import Win32RunAsAdmin
						Win32RunAsAdmin.RunAsAdministrator("python",[os.path.normpath(os.path.join(os.environ["CCP4MG"],"util","patchAsAdmin.py")),newest_version,directory])
				else:
					apply_update(newest_version,directory)

			#retval = subprocess.call(args)
			retval = subprocess.call(args,env=env)
		#os.execvp("pywrap",["pywrap",mainpy])
	else:
		if sys.platform == "win32":
			pywrap = "pywrap"
		else:
			pywrap = os.path.join(os.environ["CCP4MG"],"QtMG")
		mainpy = os.path.join(ccp4mg,"qtgui","main.py")
		os.execvp(pywrap,[pywrap,mainpy])
	print "Finished"

if __name__ == '__main__':
        runmg()
