1# $Id$
2
3namespace eval irc {}
4
5proc irc::handle_irc_commands {chatid user body type} {
6
7    set body [string trim $body]
8    if {[cequal [crange $body 0 6] "/topic "]} {
9	set command subject
10	set subject [string trim [crange $body 7 end]]
11    } elseif {[cequal [crange $body 0 8] "/subject "]} {
12	set command subject
13	set subject [string trim [crange $body 9 end]]
14    } elseif {[cequal $body "/topic"] || \
15	      [cequal $body "/subject"]} {
16	set command show_subject
17    } elseif {[cequal [crange $body 0 5] "/nick "]} {
18	set command nick
19	set nick [string trim [crange $body 6 end]]
20    } elseif {[cequal [crange $body 0 7] "/invite "]} {
21	set command invite
22	set arg [crange $body 8 end]
23	lassign [parse_body $arg "\n"] to reason
24    } elseif {[cequal [crange $body 0 5] "/join "]} {
25	set command join
26	set arg [crange $body 6 end]
27	lassign [parse_body $arg " "] room password
28    } elseif {[cequal $body "/join"]} {
29	set command join
30	set room ""
31	set password ""
32    } elseif {[cequal $body "/rejoin"]} {
33	set command rejoin
34	set password ""
35    } elseif {[cequal [crange $body 0 4] "/msg "]} {
36	set command msg
37	set arg [crange $body 5 end]
38	lassign [parse_body $arg "\n"] nick body
39    } elseif {[cequal $body "/nick"] || \
40	      [cequal $body "/msg"] || \
41	      [cequal $body "/invite"]} {
42	return stop
43    } elseif {[cequal [crange $body 0 5] "/part "]} {
44	set command leave
45	set status [string trim [crange $body 6 end]]
46    } elseif {[cequal [crange $body 0 6] "/leave "]} {
47	set command leave
48	set status [string trim [crange $body 7 end]]
49    } elseif {[cequal $body "/part"] || \
50	      [cequal $body "/leave"]} {
51	set command leave
52	set status ""
53    } else {
54	return
55    }
56
57    set xlib [chat::get_xlib $chatid]
58    set jid [chat::get_jid $chatid]
59
60    switch -- $command {
61	nick {
62	    if {![cequal $type groupchat]} return
63	    muc::change_nick $chatid $nick
64	    debugmsg plugins "NICK: $nick"
65	}
66	subject {
67	    if {![cequal $type groupchat]} return
68	    message::send_msg $xlib $jid -type groupchat -subject $subject
69	    debugmsg plugins "SUBJECT: $subject"
70	}
71	show_subject {
72	    chat::add_message $chatid $jid info \
73		"[::msgcat::mc Subject:] $chat::chats(subject,$chatid)" {}
74	}
75	invite {
76	    if {[cequal $type groupchat]} {
77		muc::invite_muc $xlib $jid $to $reason
78	    } else {
79		muc::invite_muc $xlib $to $jid $reason
80	    }
81	    debugmsg plugins "INVITE: $to $reason"
82	}
83	join {
84	    if {[cequal $type groupchat]} {
85		if {[cequal $room ""]} {
86		    set room $jid
87		} elseif {[::xmpp::jid::node $room] == ""} {
88		    set room [::xmpp::jid::jid $room [::xmpp::jid::server $jid]]
89		}
90	    }
91
92	    set chatid [chat::chatid $xlib $room]
93	    if {[catch {get_our_groupchat_nick $chatid} nick]} {
94		set nick [get_group_nick $xlib $room]
95	    }
96	    # HACK: TODO: remove usage of tokens.
97	    if {[chat::is_opened $chatid] && [info exists ::muc::tokens($chatid)]} {
98		muc::test_connection $chatid \
99			-command [namespace code [list join_if_disconnected \
100						       $xlib $room $nick $password]]
101	    } else {
102		muc::leave_group $chatid ""
103		muc::join_group $xlib $room $nick $password
104	    }
105	    debugmsg plugins "JOIN: $room $nick"
106	}
107	rejoin {
108	    if {![cequal $type groupchat]} return
109	    if {[catch {get_our_groupchat_nick $chatid} nick]} {
110		set nick [get_group_nick $xlib $jid]
111	    }
112	    muc::leave_group $chatid ""
113	    muc::join_group $xlib $jid $nick $password
114	    debugmsg plugins "REJOIN: $jid $nick"
115	}
116	msg {
117	    if {[cequal $type groupchat] && \
118		    $nick != "" && $body != ""} {
119		chat::open_to_user $xlib $jid/$nick -message $body
120		debugmsg plugins "MSG: $jid/$nick: $body"
121	    } else {
122		chat::add_message $chatid $jid error \
123		    "/msg to $nick failed" {}
124	    }
125	}
126	leave {
127	    set chat::chats(exit_status,$chatid) $status
128	    after idle [list ifacetk::destroy_win [chat::winid $chatid]]
129	    debugmsg plugins "LEAVE: $jid $status"
130	}
131    }
132    return stop
133}
134
135hook::add chat_send_message_hook [namespace current]::irc::handle_irc_commands 50
136
137proc irc::parse_body {line separator} {
138    set ne [string first $separator $line]
139    if {$ne < 0} {
140	set nick $line
141	set body ""
142    } else {
143	set nick [string range $line 0 [expr {$ne - 1}]]
144	set body [string range $line [expr {$ne + [string length $separator]}] end]
145    }
146    return [list $nick [string trim $body]]
147}
148
149proc irc::irc_commands_comp {chatid compsvar wordstart line} {
150    upvar 0 $compsvar comps
151
152    if {!$wordstart} {
153	lappend comps {/invite }
154	lappend comps {/join }
155	lappend comps {/leave }
156	lappend comps {/msg }
157	lappend comps {/nick }
158	lappend comps {/part }
159	lappend comps {/rejoin }
160	lappend comps {/subject }
161	lappend comps {/topic }
162    }
163
164    if {$wordstart && [cequal [crange $line 0 7] "/invite "] && \
165	    [string first "\n" $line] < 0} {
166	set prefix $plugins::completion::options(prefix)
167	set suffix $plugins::completion::options(suffix)
168        set jidcomps {}
169	set xlib [chat::get_xlib $chatid]
170	if {[chat::is_groupchat $chatid]} {
171	    foreach jid [roster::get_jids $xlib] {
172		if {[roster::itemconfig $xlib $jid -isuser]} {
173		    lappend jidcomps $prefix$jid$suffix
174		}
175	    }
176	} else {
177	    foreach chatid1 [lfilter chat::is_groupchat [chat::opened $xlib]] {
178		set jid [chat::get_jid $chatid1]
179		lappend jidcomps $prefix$jid$suffix
180	    }
181	}
182        set jidcomps [lsort -dictionary -unique $jidcomps]
183        set comps $jidcomps
184        debugmsg plugins "COMPLETION from roster: $comps"
185	return stop
186    }
187}
188
189hook::add generate_completions_hook [namespace current]::irc::irc_commands_comp
190
191proc irc::join_if_disconnected {xlib room nick password status} {
192    set chatid [chat::chatid $xlib $room]
193
194    debugmsg conference "TEXTJOIN: $xlib $room $status/[muc::status $chatid]"
195
196    switch -glob -- $status/[muc::status $chatid] {
197	connected/disconnected -
198	disconnected/* {
199	    muc::leave_group $chatid ""
200	    muc::join_group $xlib $room $nick $password
201	}
202	default {
203	    chat::add_message $chatid $room info \
204		[::msgcat::mc "Already joined"] {}
205	}
206    }
207}
208
209