﻿# -*- coding: utf-8 -*-
# generated by wxGlade 0.6.3 on Sun Feb 24 15:23:06 2008 from "E:\Friends\friends\Friends.wxg"

import datetime

import wx, wx.html, wx.lib.wxpTag
import wx.lib.flatnotebook as fnb

from pyxmpp.all import JID,Iq,Presence,Message,StreamError

import wx.lib.wxpTag

from glob import glob

TRANSPARENCY_STEP = 25
TRANSPARENCY_MAX  = 100
TRANSPARENCY_MIN  = 10

# ############################################################    
class ChatSession :
        def __init__(self, manager, jid, name, panel = None) :
                self.manager = manager
		self.jid = jid
                self.name = name
                self.chatPanel = panel
                
        def addHistoryText(self, jid, text) :
                if self.chatPanel :
                        try :
                                msg = glob.textDecode(text)
                                self.chatPanel.appendHistory(jid, msg)
                        except :
                                self.chatPanel.appendHistory(jid, text)
				
        def appendFileTransferSession(self, session) :
		if self.chatPanel :
			self.chatPanel.appendFileTransferSession(session)
	def close(self) :
		self.manager.closeChatSession(self)
	
# ############################################################    
class ChatSessionManager : 
	def __init__(self, parent) :
		self.parent = parent
		self._sessionList = []
		self.chatWindow = ChatWindow(self.parent, size  = (350, 300))
		
	def IsCharWinActive(self) :
		return self.chatWindow.IsActive()
	
	def showChatWin(self) :
		if self.chatWindow.IsShown() :
			return
		if not self.parent.IsShown() :
			self.parent.standWins.append(self.chatWindow)
			return
		'''
		rect = self.parent.GetRect()
		crect = self.chatWindow.GetRect()
		posx = rect[0] - 25 + rect[2]-crect[2]
		posy = rect[1] - 25 + rect[3]-crect[3]
			
		self.chatWindow.Move((posx, posy))
		'''
		self.chatWindow.Show()	
		
	def activeChatSession(self, jid) :	
                sItem =  self.findChatSession(jid)
                if not sItem:
			sItem = self.newChatSession(jid)	
		self.chatWindow.ActiveChatPanel(sItem.chatPanel)
		self.showChatWin()	
		return sItem
                
        def findChatSession(self, jid) :
                for item in self._sessionList :
                        if item.jid == jid :
                                return item
                return None
                
        def newChatSession(self, jid) :
        	try :
        		item=glob.imclient.roster.get_item_by_jid(jid)
        		name = item.name
        		if not name :
        			name = jid.as_unicode()
        	except Exception,e :
        		name = jid.as_unicode()
        		print 'new chat session key error : ', e
        		
                sItem = ChatSession(self, jid, name)        
                sItem.chatPanel = self.chatWindow.NewChatPanel(sItem) 
		self._sessionList.append(sItem)
                return sItem
                
        def closeChatSession(self, session) :
                self._sessionList.remove(session)
		if len(self._sessionList) == 0 :
			self.chatWindow.Show(False)
		
        def clearAllSessions(self):
                self._sessionList = []
                self._sessionIndex = -1  
                #self._centerNotebook.DeleteAllPages()
		self.chatWindow.Show(False)
	
# ############################################################    
class ChatHistroyCtrl(wx.html.HtmlWindow) :
	ID_SELECT_ALL = wx.NewId()
	ID_CLEAT_ALL  = wx.NewId()
	ID_COPY       = wx.NewId()
	
	def __init__(self, parent, id=-1, pos = wx.DefaultPosition, 
		size = wx.DefaultSize, style = wx.html.HW_DEFAULT_STYLE) : 
		
		wx.html.HtmlWindow.__init__(self, parent, id, pos, size, style)  
		
		self.Bind(wx.EVT_MENU, self.OnSelectAll, id = self.ID_SELECT_ALL)
		self.Bind(wx.EVT_MENU, self.OnClearAll,  id = self.ID_CLEAT_ALL)
		self.Bind(wx.EVT_MENU, self.OnCopy,      id = self.ID_COPY)
		 
		#self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
		#self.Bind(wx.EVT_MOTION,    self.OnMouseMotion)
		#self.Bind(wx.EVT_LEFT_UP,   self.OnMouseLeftUp)
		
		self.Bind(wx.EVT_RIGHT_UP,  self.OnRightUp)

	def OnMouseLeftDown(self, evt) :
		self.SetFocus()
	        	
	def OnRightUp(self, evt) :
                menu = wx.Menu()                
                menu.Append(self.ID_SELECT_ALL, u"&A全选")
		menu.Append(self.ID_COPY,       u"&C复制")
		menu.Append(self.ID_CLEAT_ALL,  u"&D清除")
		self.PopupMenu(menu)
                menu.Destroy()
	
	def OnSelectAll(self, event) :
		self.SelectAll()
	
	def OnCopy(self, event) :
		text = self.SelectionToText()
		text_data = wx.TextDataObject(text)
		if wx.TheClipboard.Open():
			wx.TheClipboard.SetData(text_data)
			wx.TheClipboard.Close()	
		
	def OnClearAll(self, event) :
		self.SetPage('')
		
	def OnLinkClicked(self, linkinfo):
		#print "OnLinkClicked"
		glob.mainFrame.OpenUrl(linkinfo.GetHref())
		
	def AppendHistory(self, jid, text) :
		now = datetime.datetime.now()
		color = '#000000'	
		if jid == glob.imclient.jid :
	                userShow = jid.node
		else :
			try :
				roster = glob.imclient.roster[jid.bare()]
				if roster.name :
					userShow = roster.name
				else :
					userShow = jid.node
			except Exception, e:
				print e
				userShow = u'&lt;%s&gt;'  % (jid.bare().as_unicode())
		
		self.Freeze()
		#userShow =  jid.bare().as_unicode()
		#showText = u'<br><font size=3 color=#808080>[%s] %s : %s</font>' % (now.strftime("%H:%M:%S"), userShow, text)		
		#showText = u'<br><font size=3 color=#%s>%s&nbsp :</font>' % (color, userShow)
	        #self.AppendToPage(showText)
		if text.startswith("http://") or text.startswith("https://") :
			text = '<a href="%s">%s</a>' % (text, text)
		elif text.startswith("www.") :
			text = '<a href="http://%s">%s</a>' % (text, text)
			
		showText = u'<br><font size=2 color=%s>%s: %s</font>' \
				% (color, userShow, text)
	        self.AppendToPage(showText)
		
		pos = self.GetScrollPos(wx.VERTICAL)
		range = self.GetScrollRange(wx.VERTICAL)
		self.ScrollLines(range - pos)
		self.Thaw()
		
# ############################################################    
class ChatActionPanel(wx.Panel) :
	def __init__(self, parent, session, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize) :
		wx.Panel.__init__(self, parent, -1, pos, size)
	
		self._mgr = wx.aui.AuiManager()
	        self._mgr.SetManagedWindow(self)
	           
	        self._historyCtrl = ChatHistroyCtrl(self, -1) 
	        self._inputCtrl = wx.TextCtrl(self, -1, style = wx.TE_MULTILINE)
	                
		self._mgr.AddPane(self._historyCtrl, wx.aui.AuiPaneInfo().CaptionVisible(False).
	                                Name('history').Center().CloseButton(False))
	        
		self._mgr.AddPane(self._inputCtrl, wx.aui.AuiPaneInfo().MinSize((-1, 50)).CaptionVisible(False).
	                                Name('input').Bottom().CloseButton(False))
	        
	        self.Bind(wx.EVT_TEXT_ENTER, self.onTextEnter, self._inputCtrl)
		self.Bind(wx.EVT_CLOSE,      self.OnClose)
	
		self._historyCtrl.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
		self._inputCtrl.Bind(wx.EVT_MOUSEWHEEL, self.OnMouseWheel)
		
	        self.session = session
	        self.session.chatPanel = self 
		self.transfers = {}
		
		self._mgr.Update()
	
	def closeSession(self) :
		self.session.close()	

	def OnClose(self, event) :
		self.session.chatPanel = None
		self.Destroy()
		print "Panel Closed"
		return True
		
	def OnMouseWheel(self, event) :
		rotation = event.GetWheelRotation()
		if rotation > 0 :
			step = TRANSPARENCY_STEP
		else :
			step = -TRANSPARENCY_STEP

		self.GetParent().GetParent().IncreaseTransparent(step)
		
	def OnContextMenu(self, event) :
                menu = wx.Menu(u'操作')                
                        
                self.PopupMenu(menu)
                menu.Destroy()
		
	def onTextEnter(self, event): 
	        to = self.session.jid
	        body = self._inputCtrl.GetValue()
		self._inputCtrl.Clear()
		bb = body.strip()
		if bb == u'-' or bb == u'_' :
			self.GetParent().GetParent().SetTransparent()
			return	
	        elif bb == u'+' or bb == u'=':
			self.GetParent().GetParent().SetTransparent(100)
			return	
		elif bb == u'==' :
			self.GetParent().GetParent().SetTransparent()
	        glob.imclient.sendChatMessage(to,body)
	        self.appendHistory(glob.imclient.jid, body)
		glob.mainFrame._taskBarIcon.MessageHandled()
		#caret = self._inputCtrl.GetCaret()
		#caret.Move(0,0)
		
	def appendHistory(self, jid, text) :
		self._historyCtrl.AppendHistory(jid, text)
		  
	def appendFileTransferSession(self, session) :
	        id = wx.NewId()
		self.transfers[id] = session
		widget = '<br><center><wxp module="FileTransfer" class="FileTransferPanel" width= "80%" height=94><param name="bgcolor" value="#F0F0F0"><param name="id" value="' + str(id) + '"></wxp></center></br>'
		self._historyCtrl.AppendToPage(widget)
		#self._historyCtrl.FindWindowById(id).BindToSession(session)

# ############################################################    
class TitlePanel(wx.Panel) :
	def __init__(self, parent, id=-1, pos=wx.DefaultPosition, size=wx.DefaultSize) :
		wx.Panel.__init__(self, parent, -1, pos, size)
		
		sizer = wx.BoxSizer(wx.HORIZONTAL)

		#bmp = wx.ArtProvider.GetBitmap(wx.ART_CROSS_MARK, wx.ART_FRAME_ICON, (12,12))
		bmp = glob.getBitmap('cancel')
		closebtn = wx.BitmapButton(self, -1, bmp, (12, 12), (bmp.GetWidth(), bmp.GetHeight()))
		self.Bind(wx.EVT_BUTTON, self.OnCloseBtnClick, closebtn)
		
		sizer.AddStretchSpacer()
		sizer.Add(closebtn, 0, wx.ALIGN_RIGHT|wx.ALL, 0)

		self.SetSizer(sizer)
		
		self.lastSize = size
		
		self.moving = False
		self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
		self.Bind(wx.EVT_MOTION,    self.OnMouseMotion)
		self.Bind(wx.EVT_LEFT_UP,   self.OnMouseLeftUp)
		
		self.Bind(wx.EVT_SIZE, self.OnSize)
	
	def OnCloseBtnClick(self, evt) :
		self.GetParent().Close()
		
	def OnSize(self, evt) :
		newSize = evt.GetSize()
		if newSize[0] != self.lastSize[0] :
			self.Layout()
		self.lastSize = newSize
		
	def OnMouseLeftDown(self, evt):
	        self.ldPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
	        self.wPos = self.ClientToScreen((0,0))
	        self.moving = True
		self.CaptureMouse()
		
	def OnMouseMotion(self, evt):
	        if evt.LeftIsDown() and self.moving :
	            dPos = evt.GetEventObject().ClientToScreen(evt.GetPosition())
	            nPos = (self.wPos.x + (dPos.x - self.ldPos.x),
	                    self.wPos.y + (dPos.y - self.ldPos.y))
	            self.GetParent().Move(nPos)

	def OnMouseLeftUp(self, evt):
		if self.moving : 
			self.ReleaseMouse()
			self.moving = False
		
# ############################################################    
import wx.lib.flatnotebook as fnb
class ChatWindow(wx.Frame) :
	TITLE_HEIGHT = 16
	
	def __init__(self, parent, pos=wx.DefaultPosition, size=wx.DefaultSize) :
                wx.Frame.__init__(self, parent, -1, u'交谈', pos, size, style = wx.SYSTEM_MENU | wx.MINIMIZE_BOX | wx.RESIZE_BORDER | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN )
                        
                self._mgr = wx.aui.AuiManager()
	        self._mgr.SetManagedWindow(self)
		
                self.SetIcon(parent._icon)
                
		#self._tilePanel = TitlePanel(self, wx.ID_ANY, size = (size[0], self.TITLE_HEIGHT))
		 
		#self._mgr.AddPane(self._tilePanel, wx.aui.AuiPaneInfo().Top().Fixed().
		#			MinSize((size[0],self.TITLE_HEIGHT)).
		#			CloseButton(False).CaptionVisible(False).Name('titlepanel'))
		
                bookStyle = fnb.FNB_NODRAG | fnb.FNB_TABS_BORDER_SIMPLE
                self._chatBook = fnb.FlatNotebook(self, wx.ID_ANY, style = bookStyle)
		self._mgr.AddPane(self._chatBook, wx.aui.AuiPaneInfo().
	                                Name('chatbook').CenterPane())
		self._mgr.Update()
		
		self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
		self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CHANGED,  self.OnPageChanged)
		self.Bind(fnb.EVT_FLATNOTEBOOK_PAGE_CLOSING,  self.OnPageClosing)

		self.Bind(wx.EVT_CLOSE,    self.OnClose)
		self.Bind(wx.EVT_SIZE,     self.OnSize)
		#self.Bind(wx.EVT_ACTIVATE, self.OnActivate)
		#self.Bind(wx.EVT_SET_FOCUS, self.OnFocus)
		
		#self.SetTransparent(TRANSPARENCY_MAX)
		'''
		if parent.IsShown() :
			self.CenterOnPanent()
		else :
			self.CenterOnScreen()
		'''
		#self.SetTransparent(50)
	
	def NewChatPanel(self, session) :
		panel = ChatActionPanel(self, session)
		self._chatBook.AddPage(panel, session.name)
		return panel
	
	def ActiveChatPanel(self, panel) :
		index = self._chatBook.GetPageIndex(panel)
		if index < 0 :
			return
		self._chatBook.SetSelection(index)
		
	def IncreaseTransparent(self, step) : 
		self.transparent += step
		self.SetTransparent(self.transparent)
		
	def SetTransparent(self, value = TRANSPARENCY_MIN) : 
		self.transparent = value
		if self.transparent > TRANSPARENCY_MAX :
			self.transparent = TRANSPARENCY_MAX
		elif self.transparent < TRANSPARENCY_MIN :
			self.transparent = TRANSPARENCY_MIN		
		wx.MiniFrame.SetTransparent(self, int(self.transparent * 2.55))
	
	def OnActivate(self, event) :
		if event.GetActive() and self.GetParent().IsActive():
			glob.mainFrame._taskBarIcon.MessageHandled()
			#print "actived"
			#print self.IsShown()
		pass
		
	def OnFocus(self, event) :
		print "focused"
		glob.mainFrame._taskBarIcon.MessageHandled()
		pass
		
	def OnSize(self, evt):
		newSize = evt.GetSize()
		#self._tilePanel.SetSize((newSize[0], self.TITLE_HEIGHT))
		self._mgr.Update()
		
	def OnMouseWheel(self, event) :
                return
		rotation = event.GetWheelRotation()
		if rotation > 0 :
			self.transparent += TRANSPARENCY_STEP
		else :
			self.transparent -= TRANSPARENCY_STEP

		self.SetTransparent(self.transparent)
	
	def OnClose(self, event) :
		self.Hide()
		return True
	
	def OnPageChanging(self, event):
		#self.log.write("Page Changing From %d To %d" % (event.GetOldSelection(), event.GetSelection()))
		event.Skip()

	def OnPageChanged(self, event):
		#self.log.write("Page Changed To %d" % event.GetSelection())
		event.Skip()

	def OnPageClosing(self, event):
		panel = self._chatBook.GetPage(event.GetSelection())
		panel.closeSession()
	
# ############################################################    
