from __main__ import pygame, SIL_Engine, exit, Fade
from socket import socket
from menu import SILTxt

from __future__ import generators

# import Twisted and install

from twisted.internet.threadedselectreactor import install
install()
from twisted.words.protocols.jabber import client, jid#
from twisted.words.xish import domish#
from twisted.internet import reactor

from pygame.locals import *
try:
    import pygame.fastevent as eventmodule
    eventmodule.init()
except ImportError:
    import pygame.event as eventmodule

# You can customize this if you use your
# own events, but you must OBEY:
#
#   USEREVENT <= TWISTEDEVENT < NUMEVENTS
#
TWISTEDEVENT = USEREVENT

def postTwistedEvent(func):
    # if not using pygame.fastevent, this can explode if the queue
    # fills up.. so that's bad.  Use pygame.fastevent, in pygame CVS
    # as of 2005-04-18.
    eventmodule.post(eventmodule.Event(TWISTEDEVENT, iterateTwisted=func))

def helloWorld():
    print "hello, world"
    reactor.callLater(1, helloWorld)
reactor.callLater(1, helloWorld)

def twoSecondsPassed():
    print "two seconds passed"
reactor.callLater(2, twoSecondsPassed)

def eventIterator():
    while True:
        yield eventmodule.wait()
        while True:
            event = eventmodule.poll()
            if event.type == NOEVENT:
                break
            else:
                yield event
                
def authd(xmlstream):#
    print "authenticated"#
    background.blit(SILTxt('Main Chat Lobby',(245,30),15,(0,128,0)).Surface,(245,30))
    background.blit(SILTxt('STATS',(22,99),48).Surface,(22,99))
    background.blit(SILTxt('Servers',(307,92),48).Surface,(307,92))
    background.blit(SILTxt('games',(419,189),48).Surface,(419,189))
    background.blit(SILTxt('games',(419,272),48).Surface,(419,272))
    background.blit(SILTxt('games',(419,356),48).Surface,(419,356))
    SIL_Engine.SIL_Surface.blit(background, (0,0) )
    SIL_Engine.SIL_Surface.blit(TextField, (21,203))

    presence = domish.Element(('jabber:client','presence'))#
    xmlstream.send(presence)#
    
    xmlstream.addObserver('/message',  debug)#
    xmlstream.addObserver('/presence', debug)#
    xmlstream.addObserver('/iq',       debug)   #

def debug(elem):#
    try: print elem.toXml().encode('utf-8').split('<body>')[1].split('</body>')[0]#
    except: print elem.toXml().encode('utf-8')
    print "="*20#


handle = str()
password = str()
field = 'handle'
def CHAT_screen():
    global handle, password
    Fade('out')
    SIL_Engine.SIL_Surface.fill((0,0,0))
    SIL_Engine.SIL_Surface.blit(pygame.image.load('chat/login.png').convert_alpha(), (178,93) )
    drawHandle(handle)
    drawPassword(password)

    pygame.display.flip()

    In_Menu = True
    while In_Menu == True:
        if pygame.event.get(pygame.QUIT): exit()
        for event in pygame.event.get():

            if event.type == pygame.KEYDOWN:
                key = event.key
                Upper = False
                if event.mod in (pygame.KMOD_CAPS, pygame.KMOD_SHIFT, pygame.KMOD_LSHIFT,
                                 pygame.KMOD_RSHIFT): Upper = True
                if 47<=key<=58 or 97<=key<=122:
                    if Upper: key -= 32
                    if field == 'handle' and len(handle) < 16: handle += chr(key)
                    elif field == 'password' and len(password) < 22: password += chr(key)
                elif key == pygame.K_BACKSPACE:
                    if field == 'handle': handle = handle[:-1]
                    else: password = password[:-1]
                elif key == pygame.K_TAB: switchField(field)
                drawHandle(handle)
                drawPassword(password)
                if event.key in (pygame.K_RETURN, pygame.K_KP_ENTER):
                    In_Menu = False
                    myJid = jid.JID(handle+'@jabber.org/SILv'+SIL_Engine.ver.split(' ')[-1])#
                    factory = client.basicClientFactory(myJid, password)#
                    factory.addBootstrap('//event/stream/authd',authd)#
                    reactor.connectTCP('jabber.org',5222,factory)#
                    # send an event when twisted wants attention
                    reactor.interleave(postTwistedEvent)
                    # make shouldQuit a True value when it's safe to quit
                    # by appending a value to it.  This ensures that
                    # Twisted gets to shut down properly.
                    shouldQuit = []
                    reactor.addSystemEventTrigger('after', 'shutdown', shouldQuit.append, True)
        
                    for event in eventIterator():
                        if event.type == TWISTEDEVENT:
                            event.iterateTwisted()
                            if shouldQuit:
                                break
                        elif event.type == QUIT:
                            reactor.stop()
                        elif event.type == KEYDOWN and event.key == K_ESCAPE:
                            reactor.stop()
                
                    pygame.quit()
                elif event.key == pygame.K_ESCAPE: In_Menu = False

    from menu import mainScreen
    SIL_Engine.DisplayScreen = mainScreen
    SIL_Engine.DisplayScreen.display()

def drawHandle(handle):
    SIL_Engine.SIL_Surface.fill((0,0,0), (269,288,181,19))
    SILTxt(handle,(273,287),13,(255,0,0)).blit()
    pygame.display.flip()
def drawPassword(password):
    SIL_Engine.SIL_Surface.fill((0,0,0), (269,315,181,19))
    SILTxt('*'*len(password),(273,314),13,(255,0,0)).blit()
    pygame.display.flip()
def switchField(f):
    global field
    if f == 'handle': field = 'password'
    else: field = 'handle'
    

CHANNEL = '#S1L'
NICK = 'SILTester'
s=socket()
background = pygame.image.load('chat/lobby.png').convert_alpha()
def CHAT_connect(handle):
    global NICK
    if handle: NICK = handle
    SERVER = 'irc.freenode.net'
    PORT = 6667
    PASSWORD = 'S1L'
    IDENT = REALNAME = NICK.lower()
    VERSION = 'SIL ('+SIL_Engine.ver+')'
    readbuffer = str()
    sendline = str()

    s.connect((SERVER,PORT))
    s.send('NICK %s\r\n' % NICK)
    s.send('USER %s %s %s :%s\r\n' % (IDENT, SERVER, SERVER, REALNAME))

    while 1:
        pygame.event.pump()
        readbuffer += s.recv(1024)
        pygame.event.pump()
        temp = readbuffer.split('\n')
        readbuffer=temp.pop()
        print '>>',readbuffer,'<<'

        for line in temp:
            line = line.rstrip()
            print line
            line = line.split()

            if line[0] == 'PING': s.send('PONG %s\r\n' % line[1])

            elif line[1] == '001': # CONNECTED
                s.send('JOIN %s %s\r\n' % (CHANNEL,PASSWORD))
          ##### Again here, textPos ?????????????
                background.blit(SILTxt('Main Chat Lobby',(245,30),15,(0,128,0)).Surface,(245,30))
                background.blit(SILTxt('STATS',(22,99),48).Surface,(22,99))
                background.blit(SILTxt('Servers',(307,92),48).Surface,(307,92))
                background.blit(SILTxt('games',(419,189),48).Surface,(419,189))
                background.blit(SILTxt('games',(419,272),48).Surface,(419,272))
                background.blit(SILTxt('games',(419,356),48).Surface,(419,356))
                SIL_Engine.SIL_Surface.blit(background, (0,0) )
                SIL_Engine.SIL_Surface.blit(TextField, (21,203))
            elif line[1] == 'PRIVMSG':
                if line[2].lower() == CHANNEL.lower():
                    nick = line[0].split('!')[0][1:]
                    text = ' '.join(line[3:])[1:]
                    drawText(nick, text)
                if line[3] == ':\x01VERSION\x01':
                    s.send('NOTICE %s :\x01VERSION %s\x01\r\n'%(line[0].split('!')[0][1:], VERSION))
            elif line[1] in ('PART','JOIN') and line[2].replace(':','').lower() == CHANNEL.lower():
                nick = line[0].split('!')[0][1:]
                if line[1] is 'PART': presence = 'left'
                else: presence = 'entered'
                print '*** %s has %s the lobby ***'%(nick,presence)

        if pygame.event.get(pygame.QUIT): exit()
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                key = event.key
                Upper = False
                if event.mod in (pygame.KMOD_CAPS, pygame.KMOD_SHIFT, pygame.KMOD_LSHIFT,
                                 pygame.KMOD_RSHIFT): Upper = True
                if 47<=key<=58 or 97<=key<=122:
                    if Upper: key -= 32
                    sendline += chr(key)
                    print sendline
                elif key == pygame.K_RETURN:
                    s.send('PRIVMSG %s :%s\r\n'%(CHANNEL,sendline))
                    drawText(NICK, sendline)
                    sendline = str()
                elif key == pygame.K_BACKSPACE: sendline = sendline[:-1]
        drawInput(sendline)
        pygame.display.flip()
        print 'ok'



def drawInput(sendline):
    SIL_Engine.SIL_Surface.fill((0,0,0), (21,432,360,20))
    SILTxt(sendline,(21,430),15,(255,255,255)).blit()
    pygame.display.flip()
    
TextField = pygame.Surface((360,360)).convert_alpha()
TextField.fill((255,255,255,0))
TextField.blit(SILTxt('*** You have entered the main chat lobby ***',(0,210),13,(255,0,0)).Surface, (0,210))
def drawText(nick, text):
    global TextField
    if nick == NICK:
        nickcolor = (128,0,0)
        textcolor = (4,76,0)
    else:
        nickcolor = (0,0,255)
        textcolor = (104,164,128)
 ###### Again here...positions?
    nick = SILTxt(nick+':', (0,210), 13, nickcolor, True)
    text = SILTxt(text, (5+nick.Surface.get_width(),210), 13, textcolor).Surface
    temp = TextField.copy()
    TextField.fill((255,255,255,0))
    TextField.blit(temp, (0,-25))
    TextField.blit(nick.Surface, (0,210))
    TextField.blit(text, (5+nick.Surface.get_width(),210))

    SIL_Engine.SIL_Surface.blit(background,(0,0))
    SIL_Engine.SIL_Surface.blit(TextField, (21,203))
