namespace eval irc {}

proc irc::handle_irc_commands {chatid user body type} {

    set body [string trim $body]
    if {[cequal [crange $body 0 6] "/topic "]} {
	set command subject
	set subject [string trim [crange $body 7 end]]
    } elseif {[cequal [crange $body 0 8] "/subject "]} {
	set command subject
	set subject [string trim [crange $body 9 end]]
    } elseif {[cequal $body "/topic"] || \
	      [cequal $body "/subject"]} {
	set command show_subject
    } elseif {[cequal [crange $body 0 5] "/nick "]} {
	set command nick
	set nick [string trim [crange $body 6 end]]
    } elseif {[cequal [crange $body 0 7] "/invite "]} {
	set command invite
	set arg [crange $body 8 end]
	lassign [parse_body $arg "\n"] to reason
    } elseif {[cequal [crange $body 0 5] "/join "]} {
	set command join
	set arg [crange $body 6 end]
	lassign [parse_body $arg " "] room password
    } elseif {[cequal $body "/join"]} {
	set command join
	set room ""
	set password ""
    } elseif {[cequal [crange $body 0 4] "/msg "]} {
	set command msg
	set arg [crange $body 5 end]
	lassign [parse_body $arg "\n"] nick body
    } elseif {[cequal $body "/nick"] || \
	      [cequal $body "/msg"] || \
	      [cequal $body "/invite"]} {
	return stop
    } elseif {[cequal [crange $body 0 5] "/part "]} {
	set command leave
	set status [string trim [crange $body 6 end]]
    } elseif {[cequal [crange $body 0 6] "/leave "]} {
	set command leave
	set status [string trim [crange $body 7 end]]
    } elseif {[cequal $body "/part"] || \
	      [cequal $body "/leave"]} {
	set command leave
	set status ""
    } else {
	return
    }

    set connid [chat::get_connid $chatid]
    set jid [chat::get_jid $chatid]

    switch -- $command {
	nick {
	    if {![cequal $type groupchat]} return
	    if {$chat::chats(status,$chatid) == "disconnected"} {
		if {[info exists ::muc::muc_password($chatid)]} {
		    set password $::muc::muc_password($chatid)
		} else {
		    set password ""
		}
		muc::join_group $connid $jid $nick $password
		debugmsg plugins "NICK -> JOIN: $nick"
	    } else {
		muc::change_nick $chatid $nick
		debugmsg plugins "NICK: $nick"
	    }
	}
	subject {
	    if {![cequal $type groupchat]} return
	    message::send_msg $jid -connection $connid \
		-type groupchat -subject $subject
	    debugmsg plugins "SUBJECT: $subject"
	}
	show_subject {
	    chat::add_message $chatid $jid info \
		"[::msgcat::mc Subject:] $chat::chats(subject,$chatid)" {}
	}
	invite {
	    if {[cequal $type groupchat]} {
		muc::invite_muc $connid $jid $to $reason
	    } else {
		muc::invite_muc $connid $to $jid $reason
	    }
	    debugmsg plugins "INVITE: $to $reason"
	}
	join {
	    if {[cequal $type groupchat]} {
		if {[cequal $room ""]} {
		    set room $jid
		} elseif {[string first @ $room] < 0} {
		    set room $room@[server_from_jid $jid]
		}
	    }
	    if {[catch {
		     get_our_groupchat_nick [chat::chatid $connid $room]
		 } nick]} {
		set nick [get_group_nick $room $::gr_nick]
	    }
	    muc::join_group $connid \
			    $room \
			    $nick \
			    $password
	    debugmsg plugins "JOIN: $room"
	}
	msg {
	    if {[cequal $type groupchat] && \
		    $nick != "" && $body != ""} {
		chat::open_to_user $connid $jid/$nick -message $body
		debugmsg plugins "MSG: $jid/$nick: $body"
	    } else {
		chat::add_message $chatid $jid error \
		    "/msg to $nick failed" {}
	    }
	}
	leave {
	    set chat::chats(exit_status,$chatid) $status
	    after idle [list ifacetk::destroy_win [chat::winid $chatid]]
	    debugmsg plugins "LEAVE: $jid $status"
	}
    }
    return stop
}

hook::add chat_send_message_hook [namespace current]::irc::handle_irc_commands 50

proc irc::parse_body {line separator} {
    set ne [string first $separator $line]
    if {$ne < 0} {
	set nick $line
	set body ""
    } else {
	set nick [string range $line 0 [expr {$ne - 1}]]
	set body [string range $line [expr {$ne + [string length $separator]}] end]
    }
    return [list $nick [string trim $body]]
}

proc irc::irc_commands_comp {chatid compsvar wordstart line} {
    upvar 0 $compsvar comps

    if {!$wordstart} {
	lappend comps {/invite }
	lappend comps {/join }
	lappend comps {/leave }
	lappend comps {/msg }
	lappend comps {/nick }
	lappend comps {/part }
	lappend comps {/subject }
	lappend comps {/topic }
    }

    if {$wordstart && [cequal [crange $line 0 7] "/invite "] && \
	    [string first "\n" $line] < 0} {
	set prefix $plugins::completion::options(prefix)
	set suffix $plugins::completion::options(suffix)
        set jidcomps {}
	set connid [chat::get_connid $chatid]
	if {[chat::is_groupchat $chatid]} {
	    foreach jid [roster::get_jids $connid] {
		if {[roster::itemconfig $connid $jid -isuser]} {
		    lappend jidcomps $prefix$jid$suffix
		}
	    }
	} else {
	    foreach chatid1 [lfilter chat::is_groupchat [chat::opened $connid]] {
		set jid [chat::get_jid $chatid1]
		lappend jidcomps $prefix$jid$suffix
	    }
	}
        set jidcomps [lsort -dictionary -unique $jidcomps]
        set comps $jidcomps
        debugmsg plugins "COMPLETION from roster: $comps"
	return stop
    }
}

hook::add generate_completions_hook [namespace current]::irc::irc_commands_comp

