<Module>
	<ModulePrefs
		title="IRCClient"

		description="IRCClient to connect to the pygowave channel"
		author="Thomas Bobb"
		author_email="Thomas.Bobb1986@googlemail.com">
		<Require feature="rpc" />
	</ModulePrefs>
	
	<UserPref name="words" datatype="hidden" />
	<Content type="html">
		<![CDATA[
        
<style type="text/css">
      body { font-size: 65%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
      ul#tabs { list-style-type: none; margin: 10px 0 0 0; padding: 0 0 0.3em 0; }
      ul#tabs li { display: inline; }
      ul#tabs li a { color: #42454a; background-color: #E5ECF9; border: 1px solid #000000; border-bottom: none; padding: 0.3em; text-decoration: none; }
      ul#tabs li a:hover { background-color: #E5ECF9; }
      ul#tabs li a.selected { color: #000; background-color: #C3D9FF; font-weight: bold; padding: 0.7em 0.3em 0.38em 0.3em; }
      div.tabContent { border: 1px solid #000000; padding: 0.5em; background-color: #C3D9FF; height: 410px;}
      div.tabContent.hide { display: none; }

    </style>
<script src ="http://wave-api.appspot.com/public/wave.js"></script>
<script type="text/javascript">
TCPSocket = window.parent.TCPSocket
IRCClient = function() {
var self = this
var conn = null
var buffer = ""
var ENDL = "\r\n"

self.onconnect = function() {}
self.onnickInUse = function() {}
self.onmessage = function() {}
self.onclose = function() {}

self.connect = function(hostname, port) {
    printMsgOnScreen("Try to connect to "+ hostname + " "+ channel, "output","status")

    conn = new TCPSocket
    conn.open(hostname, port)
    conn.onopen = conn_opened
    conn.onclose = conn_closed
    conn.onread = conn_read
}
self.close = function() {
    conn.close()
    self.onclose()
}
self.ident = function(nickname, modes, real_name) {
    send("USER", nickname + " " + modes + " :" + real_name) 
}
self.nick = function(nickname) {
    send("NICK", nickname)
}
self.join = function(channel) {
    send("JOIN", channel)
}
self.part = function(channel) {
    send("PART", channel)
}
self.disconnect = function(reason){
    send("QUIT", ":" +reason)
    conn.close()
    self.onclose()
    printMsgOnScreen("disconnected", "output","status")
}
self.quit = function(reason) {
    send("QUIT", ":" + reason)
    conn.close()
}
self.privmsg = function(destination, message) {
    send('PRIVMSG', destination + ' :' + message)
}

// Socket Callbacks
var conn_opened = function() {
    self.onopen()
}
var conn_closed = function() {
    self.onclose()
}
var conn_read = function(data) {
    buffer += data
    parse_buffer()
}

// Internal Functions
var send = function(type, payload) {
    conn.send(type + " " + payload + ENDL)
}
var parse_buffer= function() {
    var msgs = buffer.split(ENDL)
    buffer = msgs[msgs.length-1]
    for (var i=0; i<msgs.length-1; i++){
        dispatch(msgs[i])
        
    }
}
var parse_message = function(s) { 
    var msg = {}
    msg.prefix = ""
    msg.full = s

    if (s[0] == ":") {
        var first_space = s.search(" ")
        msg.prefix = s.slice(0, first_space).slice(1)
        s = s.slice(first_space + 1)
    }
    if (s.search(':') != -1) {
        var i = s.search(":")
        var payload = s.slice(i+1)
        s = s.slice(0,i-1)
        msg.args = s.split(' ')
        msg.args.push(payload)
    } else {
        msg.args = s.split(' ')
    }
    msg.type = msg.args.shift()
    return msg
}
var dispatch = function(line) {
    msg = parse_message(line)
    //console.log(msg.full)
    switch(msg.type) {
        case "PRIVMSG":
            //console.log(msg.prefix+"|"+ msg.args[0]+"|"+ msg.args.slice(1).join("[]"))
            self.onmessage(msg.prefix, msg.args[0], msg.args.slice(1).join("[]"))
            break
        case "451":
                
            client.ident("pygowave", "8 *", "pygowave")
           
            break;
        case "433":
            //ERR_NICKNAMEINUSE
            self.onnickInUse()
            break
        case "PING":
            send("PONG", ":" + msg.args)
            break
        case "001":
            printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "002":
            printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "003":
            printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "004":
            printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "332":
            //console.log("332: "+msg.args[1])
            printMsgOnScreen("Welcome to " + msg.args[1],"output" ,msg.args[1].substring(1))
            printMsgOnScreen("The topic is: "+msg.args[2],"output" ,msg.args[1].substring(1))
            clear_div(msg.args[1].substring(1),"topic")
            printMsgOnScreen(msg.args[2], "topic",msg.args[1].substring(1))
            break
        case "353":
            
            nicklist(msg.args[3], msg.args[2].substring(1))
            printMsgOnScreen("In the channel are following users", "output", msg.args[2].substring(1))
            printMsgOnScreen(msg.args[3], "output",msg.args[2].substring(1))
            break
        case "JOIN":
            //console.log(msg.args)
            joinpart(msg.full,msg.args[0].substring(1))	
            break;
        case "NICK":
            //console.log(msg.args)
            //joinpart(msg.full,msg.args[0].substring(1)) 
            break;
        case "QUIT":
            //console.log(msg.args)
            //joinpart(msg.full,msg.args[0].substring(1)) 
            break;
        case "PART":
        //console.log(msg.args)
            joinpart(msg.full,msg.args[0].substring(1))
            break;
        case "ERROR":
            printMsgOnScreen(msg.args[0], "output", "status")
            break;
        case "MODE":
           
            var changer = msg.full.substring(msg.full.search(":")+1,msg.full.search("!"))
            
            //print_output(changer + " sets mode "+msg.args[1]+ " to "+msg.args[2], "output")
            break;
        case "251":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "252":
            //printMsgOnScreen(msg.args[1]+" "+msg.args[2], "output", "status")
            break
        case "253":
            //printMsgOnScreen(msg.args[1]+" "+msg.args[2], "output", "status")
            break
        case "254":
            //printMsgOnScreen(msg.args[1]+" "+msg.args[2], "output", "status")
            break
        case "255":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "265":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "266":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "250":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "375":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "372":
            //printMsgOnScreen(msg.args[1], "output", "status")
            break
        case "376":
            printMsgOnScreen(msg.args[1], "output", "status")
            addTab(channel.substring(1),"channel");
            break
        default:
            break
        }
    }
}


var hostname = "irc.freenode.net"
var channel = "#pygowave"
var port = 6667
nickname = ""
var quitmessage = "PyGoWave IRCClient"

var client = new IRCClient()

client.onopen = function() {
    nickname = wave.getViewer().getDisplayName()
    client.nick(nickname)
    client.ident("pygowave", "8 *", "pygowave")
	client.join(channel)
}
client.onnickInUse = function() {
    nickname = nickname + "_"
    client.nick(nickname)
    client.ident(nickname, "8 *", "pygowave")
    client.join(channel)
}
client.onmessage = function(sender, place, msg) {

    var nick = sender.slice(0, sender.search("!"))
    printMsgOnScreen(nick + ": " + msg,"output", place.substring(1))

}

var clear_div = function(windowname,lokation) {
    //console.log("cleardiv: "+windowname+"."+lokation)
    document.getElementById(windowname+"."+lokation).innerHTML=" ";
}	

function sCommands(command, message){
//console.log("command: "+command)
//console.log("message: "+message)
    if(command == "join" || command == "j"){
        if(message != " " && message != null && message != ""){
        message=message.substring(0,message.search(" "));
        if(message.substring(0,1)=="#"){
        message = message.substring(1)
        }
        addTab(message, "channel")
        client.join("#"+message)
        }
    }else if(command == "part"){
       //if(command == "part"){
            //console.log(tabLinks)
            //console.log("channel:"+message+":")
            //if(message == " " || message == null || message ==""){
                //console.log("part no channel")
                //client.part("#"+currentTab)
                //removeTab() 
            //}else{
                //console.log("part with channel: "+message)
                //message=message.substring(0,message.search(" "))
                //if(message!="status"){
                //showTabByName(message)
                //client.part("#"+currentTab)
                //removeTab()
                
                //}
            //}
       //}
    } else if(command == "quit"){
    } else {
        printMsgOnScreen("/"+command +" is an unkown /command or isnt implemented yet","output","status")
    }

}
function joinChannel(name){

}
function partChannel(name){

}
var sendMessageChannel = function() {
     var input = document.getElementById(currentTab+".input")
    if(input.value.length > 0){
       if(input.value.substring(0,1)=="/"){
            //console.log("/command found")
            input.value = input.value + " "
            sCommands(input.value.substring(1,input.value.search(" ")), input.value.substring(input.value.search(" ")+1))
            input.value=""
       }else{
        printMsgOnScreen(nickname + ": " + input.value,"output",currentTab)
        client.privmsg("#"+currentTab, input.value)
        input.value=""
    }
    }
}


var joinpart = function(s, windowname) {
    
    var i = s.search("!")
    if(s.substring(1,i)!=nickname){
        str = new Array()
        str[0] =s.substring(1,i)
        var j =s.search(" ")
        str[1] = s.substring(i+1, j)
        var i = s.substring(j+1).search(" ")
        str[2] =s.substring(j+1,j+1+i)
        var i = s.substring(1).search(':')
        str[3] = s.substring(i+2)
        //console.log(str[2])
        switch(str[2]){
            case "JOIN":
            //console.log("JOIN: "+windowname)
                printMsgOnScreen(str[0] + " ("+str[1]+") has joined "+str[3], "output",windowname)
                addusertonick(str[0], windowname)
                break;
            case "PART":
            //console.log("PART: "+windowname)
                printMsgOnScreen(str[0] + " ("+str[1]+") has parted the channel", "output",windowname)
                removeuserfromnick(str[0], windowname)
                break;
            default:
                break;
            }

        }
}
function getIndexNicklist(windowname){
    for(var i=0;i<sorter.length;i++){
        if(sorter[i]==windowname){
            return i;
        }
    }
}

function addusertonick(s,windowname){
    var index = getIndexNicklist(windowname)
    //console.log("index: "+index)
    user = nickarray[index][2]
    user.push(s)
    nickarray[index][2]=user
    print_nicklist(windowname)
}
function addusertovoice(s){
    voice.push(s)
    print_nicklist()
}
function addusertoop(s){
    op.push(s)
    print_nicklist()
}
function removeuserfromnick(s, windowname){
    var index = getIndexNicklist(windowname)
    op = nickarray[index][0]
    voice = nickarray[index][1]
    user = nickarray[index][2]
    var dummi = new Array()
    for (var i=0;i<op.length;i++){
        if(op[i]!=s){
        dummi.push(op[i])
    }
}
op=dummi
var dummi = new Array()
for (var i=0;i<voice.length;i++){
if(voice[i]!=s){
dummi.push(voice[i])
}
}
voice=dummi
var dummi = new Array()
for (var i=0;i<user.length;i++){
if(user[i]!=s){
dummi.push(user[i])
}
}
user=dummi
    nickarray[index][0] = op
    nickarray[index][1] = voice
    nickarray[index][2] = user
print_nicklist(windowname)
}


var sorter = new Array()
var nickarray = new Array()



function nicklist(dummi, windowname){
//console.log("windowname: "+windowname)
var op = new Array()
var voice = new Array()
var user = new Array()

nicks = dummi.split(' ')
for (var i=0; i<nicks.length-1; i++){
var mode = nicks[i].substring(0,1)
switch(mode) {
case "@":
//console.log("Status: "+ mode + " nick: "+nicks[i].substring(1))	
op.push(nicks[i].substring(1))
break;
case "+":
//console.log("Status: "+ mode + " nick: "+nicks[i].substring(1))
voice.push(nicks[i].substring(1))
break;
default:
mode = "u"
//console.log("Status: "+ mode + " nick: "+nicks[i])
user.push(nicks[i])
break;
}
//console.log("log: "+  + " nick: "+nicks[i])
//print_output(nicks[i], "nicklistdiv")
}
sorter.push(windowname)
nickarray[sorter.length-1]= new Array(3)
nickarray[sorter.length-1][0]=op
nickarray[sorter.length-1][1]=voice
nickarray[sorter.length-1][2]=user
//console.log(nickarray)
print_nicklist(windowname)
}



function print_nicklist(windowname) {
//console.log("wind: "+windowname+" nicklistdiv")
clear_div(windowname,"nicklistdiv")
op = nickarray[sorter.length-1][0]
voice = nickarray[sorter.length-1][1]
user = nickarray[sorter.length-1][2]
op.sort(function(x,y){
var a = String(x).toUpperCase();
var b = String(y).toUpperCase();
if (a > b)
return 1
if (a < b)
return -1
return 0;
});

voice.sort(function(x,y){
var a = String(x).toUpperCase();
var b = String(y).toUpperCase();
if (a > b)
return 1
if (a < b)
return -1
return 0;
});
user.sort(function(x,y){
var a = String(x).toUpperCase();
var b = String(y).toUpperCase();
if (a > b)
return 1
if (a < b)
return -1
return 0;
});

for(var i=0; i< op.length;i++){
printMsgOnScreen("@" + op[i], "nicklistdiv",windowname)
}	
for(var i=0; i< voice.length;i++){
printMsgOnScreen("+" + voice[i], "nicklistdiv",windowname)
}  
for(var i=0; i< user.length;i++){
printMsgOnScreen(user[i], "nicklistdiv",windowname)
}
nickarray[sorter.length-1][0]=op
nickarray[sorter.length-1][1]=voice
nickarray[sorter.length-1][2]=user 
}


function checkEnterChannel(e){
var characterCode
if(e && e.which){
e = e
characterCode = e.which
}else {
e = event
characterCode = e.keyCode
}
if(characterCode == 13){
sendMessageChannel()
return false
}else{
return true
}
}
var scrollDown = function (windowname, location) {
var box = document.getElementById(windowname+'.'+location);
box.scrollTop = box.scrollHeight
}

    var linkContent = new Array();
    var divContent = new Array();
    var tabLinks = new Array();
    var contentDivs = new Array();
    var currentTab = "";
    var currentTyp = "";
    function init() {

      // Grab the tab links and content divs from the page
      var tabListItems = document.getElementById('tabs').childNodes;

      var contentItems = document.getElementById('Content').childNodes;
      for ( var i = 0; i < tabListItems.length; i++ ) {
        if ( tabListItems[i].nodeName == "LI" ) {
          var tabLink = getFirstChildWithTagName( tabListItems[i], 'A' );
          
          var id = getHash( tabLink.getAttribute('href') );
         
          tabLinks[id] = tabLink;
          contentDivs[id] = document.getElementById( id );
          
        }
      }
        for(var i =0; i<contentItems.length;i++){
           if ( contentItems[i].nodeName == "DIV" ) { 
        
        }
        }
      // Assign onclick events to the tab links, and
      // highlight the first tab
      var i = 0;

      for ( var id in tabLinks ) {
        tabLinks[id].onclick = showTab;
        tabLinks[id].onfocus = function() { this.blur() };
        if ( i == 0 ) tabLinks[id].className = 'selected';
        i++;
      }

      // Hide all content divs except the first
      var i = 0;
   
      for ( var id in contentDivs ) {
        if ( i != 0 ) contentDivs[id].className = 'tabContent hide';
        i++;
      }
    }


    function showTabByName(name) {
          var selectedId = getHash(name);
        currentTab =selectedId
      // Highlight the selected tab, and dim all others.
      // Also show the selected content div, and hide all others.
      for ( var id in contentDivs ) {
        if ( id == selectedId ) {
          tabLinks[id].className = 'selected';
          contentDivs[id].className = 'tabContent';
        } else {
          tabLinks[id].className = '';
          contentDivs[id].className = 'tabContent hide';
        }
      }
      
      scrollDown(selectedId,"output")
      // Stop the browser following the link
      return false;
    }
    
    
    
    function showTab() {
    
          var selectedId = getHash( this.getAttribute('href') );
        currentTab =selectedId
      // Highlight the selected tab, and dim all others.
      // Also show the selected content div, and hide all others.
      for ( var id in contentDivs ) {
        if ( id == selectedId ) {
          tabLinks[id].className = 'selected';
          contentDivs[id].className = 'tabContent';
        } else {
          tabLinks[id].className = '';
          contentDivs[id].className = 'tabContent hide';
        }
      }
        scrollDown(selectedId,"output")
      // Stop the browser following the link
      return false;
    }
    
        function showTabInt(selectedId) {
        
      // Highlight the selected tab, and dim all others.
      // Also show the selected content div, and hide all others.
      for ( var id in contentDivs ) {
        if ( id == selectedId ) {
          tabLinks[id].className = 'selected';
          contentDivs[id].className = 'tabContent';
        } else {
          tabLinks[id].className = '';
          contentDivs[id].className = 'tabContent hide';
        }
      }

      // Stop the browser following the link
      return false;
    }

    function getFirstChildWithTagName( element, tagName ) {
      for ( var i = 0; i < element.childNodes.length; i++ ) {
        if ( element.childNodes[i].nodeName == tagName ) return element.childNodes[i];
      }
    }

    function getHash( url ) {
      var hashPos = url.lastIndexOf ( '#' );
      return url.substring( hashPos + 1 );
    }
  
function addTab(name, typ){
     var output = document.getElementById("tabs")
    var links = output.innerHTML
    var adder = '<li><a href="#'+name+'">'+name+'</a></li> '
    links += adder
    linkContent.push(adder)
  
    output.innerHTML = links
    var output = document.getElementById("Content")
    var links2 = output.innerHTML
    if(typ == "channel"){
    adder= '<div id="' + name + '" class="tabContent hide"><div id="'+name+'.topic" style="position:relative;width: 100%;height: 50px;position:relative;background-color: #C3D9FF;text-align: left;"></div><div id="'+name+'.output" style=" position:absolute; width: 79%;height: 300px;background-color: #C6C4A8;text-align: left; overflow: auto;"></div><div id="'+name+'.nicklistdiv" style="	position:absolute;right: 2px;width: 20%;height: 300px;background-color: #CADEF4;text-align: left;"></div>test<br><div id="'+name+'.navigation" style="position:relative;left:0px;top:300px;width: 100%;height: 50px;background-color: #C6C4A8;"><input type=text id="'+name+'.input" onKeyPress="checkEnterChannel(event)" style="width: 99%;"><br><button onclick="sendMessageChannel()">Send</button><br></div></div>'
    }else if(typ == "status"){
    adder='<div id="' + name + '" class="tabContent hide"><div id="'+name+'.output" style="position:relative;width: 100%;height: 350px;position:relative;background-color: #C6C4A8;text-align: left; overflow: auto;"></div><div id="'+name+'.navigationqry" style="    position:relative;left: 0px;width: 100%;height: 50px;background-color: #C6C4A8;"><input type=text id="'+name+'.input" onKeyPress="" style="width: 99%;"><br><button onclick="">Send</button><br></div></div> '
    }else{
    adder = '<div id="' + name + '" class="tabContent hide"><h2>test :)</h2><div><p>A</p><p>BC</p></div></div> '
    }
    links2=links2+adder
    divContent.push(adder)
   
   output.innerHTML = links2
   init()
   showTabByName("#"+name)
   
   
}
function removeTab(){
    if(currentTab!=""){
        
        dummi = new Array()
        dummi2 = new Array()
	//console.log("divContent: "+divContent)
        
        for(var i =0;i<linkContent.length;i++){
            if(linkContent[i].indexOf('#'+currentTab+'">')==-1){
                dummi.push(linkContent[i])
                dummi2.push(divContent[i])
                }
        }
        linkContent = dummi
        divContent = dummi2
        //console.log("divContent: "+divContent)
        dummi = ""
        dummi2 = ""
        for(var i =0;i<linkContent.length;i++){
            dummi = dummi + linkContent[i]
            dummi2 = dummi2 + divContent[i]
        }
        //console.log(dummi)
        //console.log(dummi2)
        var element = document.getElementById("tabs")
        element.innerHTML = dummi
        var element = document.getElementById("Content")
        element.innerHTML = dummi2
        
        init()
        dummi = new String();
        if(linkContent[0]==undefined){
            currentTab = ""
        }else{
            
            dummi = linkContent[0].substring(linkContent[0].indexOf("href"))
           
            showTabByName(dummi.substring(6,dummi.indexOf(">")-1))
        }
        
    }
    
}
function stringToRegExp(pattern, flags){
    return new RegExp(
        pattern.replace(/[\[\]\\{}()+*?.$^|]/g, function(m){return '\\'+m;}),
        flags);
}

function printMsgOnScreen(s,location,windowname){
     for(var i =0;i<linkContent.length;i++){
     
        if(linkContent[i].indexOf('#'+windowname+'">')!=-1){
            //console.log("link: "+linkContent[i])
            var divs = document.getElementById(windowname+"."+location)
            if(s!= undefined){
                // make divs HTML safe
                s = s.replace("&", "&amp;", "g")
                s = s.replace("<", "&lt;", "g")
                s = s.replace(">", "&gt;", "g")
                s = s.replace('"', "&quot;", "g")
                s = s.replace("'", "&#39;", "g")
                var previousInnerHTML = new String();
                    if(divs.innerHTML != null){
                    previousInnerHTML =   divs.innerHTML
                } else {
                    previousInnerHTML = ""
                }
                previousInnerHTML = previousInnerHTML.concat(s +"<br>")
                divs.innerHTML = previousInnerHTML
                if(location == "output"){
                    scrollDown(windowname,location)
                }
            }
	    //console.log(divContent[i])
            dummi = divContent[i].substring(divContent[i].indexOf('overflow: auto')+17)
	    //console.log(dummi)
            dummi2=dummi
            dummi = dummi.substring(0,dummi.indexOf('</div>'))
    //console.log(dummi)
            dummi3=dummi
            //console.log("d:"+dummi)
            dummi +=s+"<br>"
		    //console.log(dummi)
            divContent[i]= divContent[i].substring(0,divContent[i].indexOf('overflow: auto')+17)+dummi+dummi2.substring(dummi.indexOf('</div>')+dummi3.length+1)
    //console.log(divContent[i])
  
        }
                    

     }
}
   
    gadgets.util.registerOnLoadHandler(function () {init();addTab("status","status");client.connect(hostname,port);});
     </script>
    <h1>PyGoWave IRCClient</h1>
<div>
    <ul id="tabs">
    </ul>
</div>
<div id = Content>
    </div>
    Changelog: /join is now supported
     

                                                        
     ]]>
	</Content>
</Module>
