"""
     qtgui/MGWebBrowser.py: CCP4MG Molecular Graphics Program
     Copyright (C) 2001-2008 University of York, CCLRC
     Copyright (C) 2009-2010 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
from PyQt4 import QtWebKit, QtGui, QtCore
import urllib2
import os

class MGWebPage(QtWebKit.QWebPage):
	def acceptNavigationRequest(self,frame=None,request=None,type=None):
		for type in self.customTypes:
			if os.path.basename(str(request.url().path())).endswith(type):
				self.emit(QtCore.SIGNAL("CustomMimeTypeRequested"),request.url())
				return False # Not sure it helps us much.
		else:
			return True

	def __init__(self,parent=None):
		QtWebKit.QWebPage.__init__(self,parent)
		self.customTypes = []

	def customMimeTypes(self):
		return self.customTypes

	def setCustomMimeTypes(self,types=None):
		if types and type(types)==tuple or type(types)==list:
			self.customTypes = types

        def javaScriptConsoleMessage(self, message, lineNumber, sourceID):
              print message.toUtf8(), lineNumber, sourceID

class MGWebView(QtWebKit.QWebView):

	def createWindow(self,type=None):
		view = MGWebView()
		view.setCustomMimeTypes(self.customMimeTypes())
		self.emit(QtCore.SIGNAL("NewWindowRequested"),view)
		return view

	def LoadStarted(self,):
		icon = QtGui.QIcon()
		self.emit(QtCore.SIGNAL("IconReady"),(icon,self))

	def setTarget(self,target=None):
		self.target=target

	def LoadFinished(self,ok=None):
		icon = self.icon()
		#print "Finished", self.target
		if self.target:
			myurl = self.url()
			myurl.setFragment(self.target)
			self.setTarget('')
			self.load(myurl)
		self.emit(QtCore.SIGNAL("IconReady"),(icon,self))

	def customMimeTypes(self):
		return self.page().customMimeTypes()

	def setCustomMimeTypes(self,types=None):
		if types and type(types)==tuple or type(types)==list:
			self.page().setCustomMimeTypes(types)

	def CustomMimeTypeRequested(self,url=None):
		if url: self.emit(QtCore.SIGNAL("CustomMimeTypeRequested"),url)

	def copyHighlighted(self):
		QtGui.QApplication.clipboard().setText(self.selectedText())

	def __init__(self,parent=None):
		QtWebKit.QWebView.__init__(self,parent)
		self.mgpage = MGWebPage(self) 
		self.setPage(self.mgpage)
		self.connect(self.mgpage,QtCore.SIGNAL("CustomMimeTypeRequested"),self.CustomMimeTypeRequested)
		self.connect(self.mgpage,QtCore.SIGNAL("statusBarMessage(const QString&)"),self.StatusBarMessage)
		self.connect(self.mgpage,QtCore.SIGNAL("linkHovered(const QString &, const QString &, const QString &)"),self.LinkHovered)
		self.connect(self,QtCore.SIGNAL("loadFinished(bool)"),self.LoadFinished)
		self.connect(self,QtCore.SIGNAL("loadStarted()"),self.LoadStarted)
		shortcut = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+C", "Copy")),self)
		self.connect(shortcut,QtCore.SIGNAL("activated()"),self.copyHighlighted)
		"""
		#So we need a preferences pane for browser....
    		self.settings().setFontSize(QtWebKit.QWebSettings.MinimumFontSize,9)
    		self.settings().setFontSize(QtWebKit.QWebSettings.DefaultFontSize,16)
    		self.settings().setFontSize(QtWebKit.QWebSettings.DefaultFixedFontSize,18)
    		self.settings().setFontFamily(QtWebKit.QWebSettings.StandardFont,"Times")
		"""
		self.setTarget('')

	def LinkHovered(self,link,title,content):
		self.emit(QtCore.SIGNAL("StatusBarMessage"),(link))

	def StatusBarMessage(self,message=None):
		self.emit(QtCore.SIGNAL("StatusBarMessage"),(message))

class MGTabWidget(QtGui.QTabWidget):
	def contextMenuEvent(self,event=None):
		print event

	def __init__(self,parent=None):
		QtGui.QTabWidget.__init__(self,parent)

class MGBrowserWindow(QtGui.QMainWindow):
	def StatusBarMessage(self,message=None):
		sb = self.statusBar()
		sb.showMessage(message)

	def setCustomMimeTypes(self,types=None):
		for i in range(self.tab.count()):
			widget = self.tab.widget(i)
			if hasattr(widget,"setCustomMimeTypes") and callable(widget.setCustomMimeTypes):
				widget.setCustomMimeTypes(types)

	def NewWindowRequested(self,view=None):
		if view:
			self.tab.addTab(view,view.title())
			view.connect(view,QtCore.SIGNAL("CustomMimeTypeRequested"),self.CustomMimeTypeRequested)
			self.connect(view,QtCore.SIGNAL("NewWindowRequested"),self.NewWindowRequested)
			self.connect(view,QtCore.SIGNAL("StatusBarMessage"),self.StatusBarMessage)
			self.connect(view,QtCore.SIGNAL("titleChanged(const QString &)"),self.setTabTitles)
			self.connect(view,QtCore.SIGNAL("IconReady"),self.IconReady)

	def setTabTitles(self,title=None):
		for i in range(self.tab.count()):
			widget = self.tab.widget(i)
			if hasattr(widget,"title") and callable(widget.title):
				self.tab.setTabText(i,widget.title())
		self.setWindowTitle('CCP4mg Browser: '+self.tab.tabText(self.tab.currentIndex()))
		widget = self.tab.widget(self.tab.currentIndex())
		if hasattr(widget,"url") and callable(widget.url):
			if hasattr(widget.url(),"toString") and callable(widget.url().toString):
				self.addressEdit.setText(widget.url().toString())
		
		self.setHistoryActionAvailability()

        def DeleteTab(self,ok=False):
		if self.tab.count()>1:
			self.tab.removeTab(self.tab.currentIndex())
		self.setHistoryActionAvailability()

	def CustomMimeTypeRequested(self,url=None):
		self.emit(QtCore.SIGNAL("CustomMimeTypeRequested"),url)


	def loadMgHelp(self,file='',plugin=''):
	  if plugin:
	    filename = os.path.join(os.environ['CCP4MG'],'qtgui','plugins',plugin,file)
	    self.loadFile(filename)
	    return
	  self.loadFile(os.path.join(os.environ['CCP4MG'],'help',file))
	  
        def loadFile(self,file):
	   ftest = file
	   target = None
	   if file.find('#')>0: ftest,target = file.split('#',1)
	   if os.path.exists(ftest):
	      url = QtCore.QUrl.fromLocalFile(file)
	   elif os.path.exists(ftest+'.html'):
	      urlName = ftest+'.html'
	      if target:
		 urlName = urlName +'#' + target
	      url = QtCore.QUrl.fromLocalFile(urlName)
	   elif not file[0:4] == 'http':
	      url =  QtCore.QUrl("http://"+file)
	   else:
	      url = file
           self.loadPage(url)
	   
	def loadPage(self,url):
		target = ''
		if url.scheme()=='file':
			if str(url.path().toAscii()).find('#')>0:
				urlpath,target=str(url.path().toAscii()).split('#',1)
				url = QtCore.QUrl.fromLocalFile(urlpath)
		if url.isValid:
			pass
		else:
			return
		#print "OK, trying",url.path(),target
		if self.tab.count()>0:
			widget = self.tab.currentWidget()
			if hasattr(widget,"load") and callable(widget.load):
				try:
					widget.setTarget(target)
					widget.load(url)
				except:
					exc_type, exc_value,exc_tb = sys.exc_info()[:3]
					print exc_type
					print exc_value
					import traceback
					traceback.print_tb(exc_tb)
				return
		view = MGWebView()
		view.connect(view,QtCore.SIGNAL("CustomMimeTypeRequested"),self.CustomMimeTypeRequested)
		self.connect(view,QtCore.SIGNAL("NewWindowRequested"),self.NewWindowRequested)
		self.connect(view,QtCore.SIGNAL("StatusBarMessage"),self.StatusBarMessage)
		self.connect(view,QtCore.SIGNAL("titleChanged(const QString &)"),self.setTabTitles)
		self.connect(view,QtCore.SIGNAL("IconReady"),self.IconReady)
		self.tab.addTab(view,"MGWebBrowser")
		
	def IconReady(self,args=None):
		icon,view = args
		for i in range(self.tab.count()):
			widget = self.tab.widget(i)
			if widget is view:
				self.tab.setTabIcon(i,icon)

	def __init__(self,parent=None):
		QtGui.QMainWindow.__init__(self,parent)
		self.tab = MGTabWidget(self)
		pb = QtGui.QPushButton()
		pb.setText(self.tr("Delete tab"))
		self.tab.setCornerWidget(pb)
		self.connect(pb,QtCore.SIGNAL("clicked(bool)"),self.DeleteTab)
		view = MGWebView()
		view.connect(view,QtCore.SIGNAL("CustomMimeTypeRequested"),self.CustomMimeTypeRequested)
		self.connect(view,QtCore.SIGNAL("NewWindowRequested"),self.NewWindowRequested)
		self.connect(view,QtCore.SIGNAL("StatusBarMessage"),self.StatusBarMessage)
		self.connect(view,QtCore.SIGNAL("titleChanged(const QString &)"),self.setTabTitles)
		self.connect(view,QtCore.SIGNAL("IconReady"),self.IconReady)
		self.tab.addTab(view,"MGWebBrowser")
		self.setCentralWidget(self.tab)

		toolbar = self.addToolBar("ToolBar")
		self.backAction = QtGui.QAction(self)
		self.forwardAction = QtGui.QAction(self)
		self.backAction.setText(self.tr("Back"))
		self.forwardAction.setText(self.tr("Forward"))
		toolbar.addAction(self.backAction)
		toolbar.addAction(self.forwardAction)
		self.addressEdit = QtGui.QLineEdit()
		self.searchEdit = QtGui.QLineEdit()
		searchStyle = """QLineEdit {
             		border: 1px solid gray;
             		border-radius: 12;
			border-style: inset;
             		padding: 0 3px;
         	}
	 	"""
		self.searchEdit.setStyleSheet(searchStyle)
		editSplitter = QtGui.QSplitter()
		editSplitter.addWidget(self.addressEdit) 
		editSplitter.addWidget(self.searchEdit)
		self.connect(self.addressEdit,QtCore.SIGNAL("returnPressed()"),self.addressEdited)
		self.connect(self.searchEdit,QtCore.SIGNAL("returnPressed()"),self.searchEdited)
		editSplitter.setStretchFactor(0,2)
		toolbar.addWidget(editSplitter)
		self.connect(self.backAction,QtCore.SIGNAL("triggered(bool)"),self.historyBack)
		self.connect(self.forwardAction,QtCore.SIGNAL("triggered(bool)"),self.historyForward)
		self.setHistoryActionAvailability()
		self.connect(self.tab,QtCore.SIGNAL("currentChanged(int)"),self.setTabTitles)
		sb = self.statusBar()
		self.searchEngineString = "http://www.google.com/search?q="

		reloadShortcut = QtGui.QShortcut(QtGui.QKeySequence(self.tr("Ctrl+R")),self)
                reloadShortcut.activated.connect(self.reloadCurrentTab)

	def reloadCurrentTab(self):
                self.tab.currentWidget().reload()

	def searchEdited(self):
		text =  self.searchEdit.text().replace(QtCore.QRegExp("\\s+"),QtCore.QString("+"))
		self.loadPage(QtCore.QUrl(self.searchEngineString+text))

	def addressEdited(self):
		self.loadPage(QtCore.QUrl(self.addressEdit.text()))

	def setHistoryActionAvailability(self):
		widget = self.tab.currentWidget()
		if hasattr(widget,"history") and callable(widget.history):
			history = widget.history()
			if history.canGoForward():
				self.forwardAction.setEnabled(True)
			else:
				self.forwardAction.setEnabled(False)
			if history.canGoBack():
				self.backAction.setEnabled(True)
			else:
				self.backAction.setEnabled(False)


	def historyForward(self):
		widget = self.tab.currentWidget()
		if hasattr(widget,"history") and callable(widget.history):
			history = widget.history()
			if history.canGoForward():
				history.goToItem(history.forwardItem())
		self.setHistoryActionAvailability()

	def historyBack(self):
		widget = self.tab.currentWidget()
		if hasattr(widget,"history") and callable(widget.history):
			history = widget.history()
			if history.canGoBack():
				history.goToItem(history.backItem())
		self.setHistoryActionAvailability()

	def minimumSizeHint(self):
        	return QtCore.QSize(QtGui.QApplication.desktop().width()/3, QtGui.QApplication.desktop().height()/2)

if __name__ == '__main__':
	if "-quit" in sys.argv:
		sys.exit()
	def DoSomething(url=None):
		print "Do something with", url

	app = QtGui.QApplication(sys.argv)
	try:
		if sys.platform == 'win32':
     			homedir = os.environ.get('USERPROFILE')
		else:
			homedir = os.environ.get('HOME')
	except:
		pass
	if homedir and os.path.exists(homedir):
		webkit_db = os.path.join(homedir,'.qwebkit_idb')
		if os.path.exists(webkit_db):
        		QtWebKit.QWebSettings.setIconDatabasePath(webkit_db)
		else:
			try:
				os.mkdir(webkit_db)
        			QtWebKit.QWebSettings.setIconDatabasePath(webkit_db)
			except:
				# Favicons disabled
				pass

	browser = MGBrowserWindow()
	browser.connect(browser,QtCore.SIGNAL("CustomMimeTypeRequested"),DoSomething)
	browser.setCustomMimeTypes(["pdb","mtz"])
	browser.show()
	browser.raise_()
	#browser.loadPage(QtCore.QUrl("file:///Users/stuart/Qt4.4/test.html"))
	#browser.loadPage(QtCore.QUrl("file:///y/people/mcnicholas/Qt4.4/test.html"))
	#browser.loadPage(QtCore.QUrl("file:///richelieu/stuart/ccp4-jhbuild-distutils/WebGL/js-pimple.html"))
        if len(sys.argv)>1:
	  browser.loadPage(QtCore.QUrl(sys.argv[1]))

	sys.exit(app.exec_())
