# "URL commands" -- a Tkabber chat plugin.
# Provides two IRC-style chat commands that allow the
# user to view the list of URLs present in the current 
# chat window and open them in the browser.
# Plugin implementation by
#    Gebb
# Original idea and main code by
#    Konstantin Khomoutov <flatworm@users.sourceforge.net>
#
# Usage:
# /listurls
#    Shows the list of URLs in the chat window.
#
# /browseurl ?n?
#    Opens the n-th URL in the browser. Omit the argument 
#    to open the last URL in the list.

package require msgcat

namespace eval urlcmd {
	::msgcat::mcload [file join [file dirname [info script]] msgs]

	hook::add generate_completions_hook \
		[namespace current]::command_comps
	hook::add chat_send_message_hook \
		[namespace current]::handle_command 16
}

proc urlcmd::command_comps {chatid compsvar wordstart line} {
	upvar 0 $compsvar comps
    
	if {!$wordstart} {
		lappend comps {/listurls } {/browseurl }
	}
}

proc urlcmd::handle_command {chatid user body type} {
	
	# Detect the command.
	if {[string match {/listurls*} $body]} {
		set cmd /listurls
	} elseif {[string match {/browseurl*} $body]} {
		set cmd /browseurl
	} else return

	# Get the URL list.
	set urls [geturls $chatid]

	# If the list was requested, show it and exit.
	if {[string equal $cmd "/listurls"]} {
		if {[llength $urls] == 0} {
			show error $chatid [::msgcat::mc "No URLs were found."]
		} else {
			listurls $urls $chatid
		}
		return stop
	}

	# If we got here, the command is definitely /browseurl.
	set maxindex [expr {[llength $urls] - 1}]
	if {$maxindex < 0} {
		# Nothing to show: URL list is empty.
		show error $chatid [::msgcat::mc "No URLs were found."]
		return stop
	}
	
	# Ignore everything but the first line.
	set firstline [lindex [split $body \n] 0]
	# Get the command argument (URL index).
	set uindex [string trim [string range $firstline [string length $cmd] end]]
	
	# Validate the URL index.	
	if {$uindex == ""} {
		set uindex end 
	} elseif {![string is integer $uindex]} {
		show error $chatid [::msgcat::mc "Invalid URL index.\
			Index must be an integer number."]
		return stop
	} elseif {$uindex > $maxindex || $uindex < 0 } {
		set errmsg [::msgcat::mc "URL index was\
			out of range. Valid range is from 0\
			to %s inclusively." $maxindex]
		show error $chatid $errmsg
		return stop
	}
	
	# Everything is OK, navigate to the requested URL.
	browseurl [lindex $urls $uindex]
	# We're done, stop processing hook handlers.
	return stop
}

# Returns a list of URLs present
# in the $chatid window.
#
proc urlcmd::geturls chatid {
	set cw [chat::chat_win $chatid]
	set out [list]
	
	foreach {a b} [$cw tag ranges url] {
		set u [$cw get $a $b]
		# Do not add existing URLs.
		if { ![info exists urls($u)] } {
			set urls($u) 1
			lappend out $u
		}
	}
	set out
}

# Shows the specified list of URLs
# in the $chatid window.
#
proc urlcmd::listurls {urls chatid} {
	set ix 0
	set msg ""
	append msg \n[::msgcat::mc "Available URL list"]
	foreach url $urls {
		append msg "\n$ix: $url"
		incr ix
	}
	show info $chatid $msg
}

# $type should be either "info" or "error"
proc urlcmd::show {type chatid msg} {
	set jid [chat::get_jid $chatid]
	set cw [chat::chat_win $chatid]

	chat::add_message $chatid $jid $type $msg {}
}

