Object subclass: #STalkerObject
        instanceVariableNames: ''
        category: 'IRCBot'!

!STalkerObject methodsFor: 'logging'!

log: aString
    console log: 'RECV - ', aString.
!

info: aString
    console log: 'INFO - ', aString.
!

error: aString
    console log: 'ERRR - ', aString.
!

warning: aString
    console log: 'WARN - ', aString.
! !

STalkerObject subclass: #STalkerPlugin
        instanceVariableNames: 'socket'
        category: 'IRCBot'!
!STalkerPlugin methodsFor: 'initializing'!

socket
	^socket
!

socket: aSocket
	socket := aSocket.
!

raw: aString
        socket write: aString, String crlf.
!

say: aString to: aChannel
        self raw: 'PRIVMSG ', aChannel, ' :', aString.
!

handle: data
	^(self pattern: data) ifTrue: [self doYourStuff: data]
! !

STalkerPlugin subclass: #PingPlugin
        instanceVariableNames: ''
        category: 'IRCBot'!

!PingPlugin methodsFor: 'initializing'!

pattern: aLine
	^ (RegularExpression fromString: '^PING :(.+)') test: aLine.
!

doYourStuff: data
    self info: 'Answering ping to: ', data.
	self raw: (data replaceRegexp: 'PING' with: 'PONG').
! !

STalkerPlugin subclass: #FreenodeLoginPlugin
        instanceVariableNames: ''
        category: 'IRCBot'!

!FreenodeLoginPlugin methodsFor: 'initializing'!

nickname
        ^ 'StalkerBot', 1000 atRandom.
!

password
        ^ nil
!

realName
        ^ 'JTalk/NodeJS Bot'.
!

pattern: aLine
	^ (RegularExpression fromString: '^.*No Ident response.*') test: aLine
!

doYourStuff: data
	self info: 'Loging in as ', self nickname.
	self raw: 'NICK ', self nickname.
	self raw: 'USER ',  self nickname, ' 8 *  : ', self realName .
! !

STalkerPlugin subclass: #AutojoinPlugin
        instanceVariableNames: 'channels'
        category: 'IRCBot'!

!AutojoinPlugin methodsFor: 'initializing'!

initialize
    super initialize.
    channels := Array new.
    channels add: '#jtalk-bots'.
!

addChannel: aString
        channels add: aString.
!

pattern: aLine
        ":StalkerBot MODE StalkerBot :+i"
        ^ (RegularExpression fromString: '^.+MODE.+\+i.*') test: aLine
!

doYourStuff: data
	self info: 'Autojoining channels.'.
	channels do: [ :channelName |
	                    self raw: 'JOIN ', channelName.
	                    self info: 'Joining ', channelName. ].
! !

STalkerObject subclass: #IRCBot
        instanceVariableNames: 'plugins'
        category: 'IRCBot'!

!IRCBot methodsFor: 'initializing'!


initialize
    super initialize.
    self initializeWithPlugins: (Array with: PingPlugin with: AutojoinPlugin with: FreenodeLoginPlugin).
!

initializeWithPlugins: pluginsToAdd
    self addPlugins: (Array withAll: pluginsToAdd).
!

addPlugins: anArray
    plugins := anArray collect: [:aPlugin| self spawnPlugin: aPlugin].
!

spawnPlugin: aPlugin
    self info: 'Plugin loaded: ', aPlugin name.
    ^(aPlugin new socket: socket).
!

start
    console log: socket.
    socket on: 'connect' callback: [ self info: 'Hem connectat'] .
    socket on:'data' callback:[ :data | data linesDo: [:line |
 	      	 	self log: line.
			    line = '' ifFalse:[ self handle: line]]].
    socket setEncoding: 'ascii'.
    socket setNoDelay.
    socket connect: 6667 host: 'irc.freenode.org'.
!

handle: data
	plugins do:[:plugin | plugin handle: data ]
! !

!IRCBot class methodsFor: 'initialization'!
initialize
    socket :=  < new require('net').Socket()>.
!

main
	self new start
! !