###
#
# @author:  Rune Madsen <Rune@DataIT.net> for Inivis
# @version; $Id: ac3dobjlib.tcl,v 1.12 2003/10/06 07:21:19 rm Exp $
#


proc obj_refresh {} {

	global objdir
	global prefs_object_library_path

	set objdir $objdir/
	set prefs_object_library_path $prefs_object_library_path/
	regsub -all "//+" $objdir "/" objdir
	regsub -all "//+" $prefs_object_library_path "/" prefs_object_library_path

	set w .ol.a.dir.a.content
	set list [glob -nocomplain -tails -types d -directory $objdir "*"]
	set list [lsort $list]

	$w delete 0 end

	if { $objdir != $prefs_object_library_path } {
		$w insert end ".."
	}

	foreach f $list {
		regsub ".*/" $f "" f
		$w insert end $f
	}

	if { $objdir != $prefs_object_library_path } {
		set leaf [file tail $objdir]
	} else {
		set leaf "\[root\]"
	}
	.ol.a.obj configure -text "Objects in $leaf"

	set w .ol.a.obj.a.content
	set list [glob -nocomplain -tails -types f -directory $objdir "*.ac"]
	set list [lsort $list]

	$w configure -state normal
	$w delete 0 end
	if { [llength $list] > 0 } {
		foreach f $list {
			regsub ".*/" $f "" f
			regsub "\.ac$" $f "" f
			$w insert end $f
		}
	} else {
		$w insert end "<no objects>"
		$w configure -state disabled
	}
}


proc obj_load { path name } {
	set filepath $path/
	append filepath $name ".ac"
	ac3d load_file $filepath
}


proc obj_save { path name } {

	global obj_tosave

	set boxtitle "Save $obj_tosave"

	if { $path == "" || $name == "" } {
		tk_messageBox -title $boxtitle -message "Please specify an object name"
		return false
	}

	if { ! [regexp "\.ac$" $name] } {
		set name $name.ac
	}

	set filepath $path/$name

	if { [file isdirectory $filepath] } {
		tk_messageBox -title $boxtitle -message "Please specify another object name"
		return false
	}

	if { [file exists $filepath] } {
		set ans [tk_messageBox -title $boxtitle -message "Object already exists.\nDo you want to replace it?" -type yesno]
		if { $ans != "yes" } {
			return false
		}
	}

	if { $obj_tosave == "selection" } {
		ac3d save_selection_ac $filepath
	} else {
		ac3d save_ac $filepath
	}

	# default to "save everything" for "replace..."
	set obj_tosave "everything"

	obj_refresh
	return true
}


proc obj_save_dlg { cat } {

	global objsub
	global leafcat
	global obj_tosave

	set name ""
	regsub ".*/" $objsub "" leafcat
	if { $leafcat == "" } { set leafcat "\[root\]" }

	toplevel .osd
	wm title .osd "Store"
	wm transient .osd [winfo toplevel [winfo parent .osd]]

	frame .osd.a
	label .osd.a.catl -text "Category:"
	label .osd.a.cat -text $leafcat

	label .osd.a.objnamel -text "Object name:"
	entry .osd.a.objname -textvariable name

	frame .osd.a2
	radiobutton .osd.a2.saveall -text "Store everything" -value "everything" -variable obj_tosave
	radiobutton .osd.a2.savesel -text "Store selected" -value "selection" -variable obj_tosave
	.osd.a2.saveall select

	frame .osd.b
	button .osd.b.ok -text "Store" -command { if { [obj_save $objdir $name] } { destroy .osd } }
	button .osd.b.c -text "Cancel" -command { destroy .osd }

	bind .osd.a.objname <Return> { if { [obj_save $objdir $name] } { destroy .osd } }

	grid .osd.a.catl .osd.a.cat -sticky w -padx 4 -pady 2
	grid .osd.a.objnamel .osd.a.objname -sticky w -padx 4 -pady 2
	pack .osd.a -side top
	pack .osd.a2.saveall -side top -anchor w
	pack .osd.a2.savesel -side top -anchor w
	pack .osd.a2 -side top -pady 3
	pack .osd.b.ok -side left
	pack .osd.b.c -side left
	pack .osd.b -side top -pady 4 -ipadx 4

	centre_window_on_screen .osd
	grab .osd
}


proc obj_delete_file { dir name } {

	if { $dir == "" || $name == "" } { return }

	set filepath $dir/$name.ac
	if { ! [file exists $filepath] } { return }

	set choice [tk_messageBox -type yesno -default no -title "Delete model" -message "Are you sure you want to delete $name?"]
	if { $choice == "yes" } {
		file delete $filepath
		puts "Deleted model $filepath"
	}
	obj_refresh
}


proc obj_verify_new_subcat { path cat } {

	set newcat $path/$cat

	if { $path == "" || $cat == "" } {
		tk_messageBox -title "Create new category" -message "Please enter a category name"
		return false
	}

	if { [file isdirectory $newcat] } {
		tk_messageBox -title "Create new category" -message "Category already exists"
		return false
	}

	if { [file exists $newcat] } {
		tk_messageBox -title "Create new category" -message "Please choose another category name"
		return false
	}

	file mkdir $newcat
	obj_refresh

	puts "Created new sub-category $cat"
	return true
}


proc obj_new_subcat { path } {

	global gpath

	set gpath $path
	set cat ""

	toplevel .ons
	wm title .ons "Create new category"
	wm transient .ons [winfo toplevel [winfo parent .ons]]

	label .ons.msg -text "Enter category name:"
	entry .ons.cat -textvariable cat
	frame .ons.b
	button .ons.b.ok -text "OK" -command { if { [obj_verify_new_subcat $gpath $cat] == true } { destroy .ons } }
	button .ons.b.cancel -text "Cancel" -command { destroy .ons }

	bind .ons.cat <Return> { if { [obj_verify_new_subcat $gpath $cat] == true } { destroy .ons } }

	pack .ons.msg -side top -padx 3 -pady 3
	pack .ons.cat -side top -pady 3
	pack .ons.b.ok -side left -pady 3
	pack .ons.b.cancel -side right -pady 3
	pack .ons.b -side bottom

	centre_window_on_screen .ons
}


proc obj_delete_cat { dir } {

	global tcl_platform
	global AC3D_HOME

	set w .ol.a.dir.a.content

	set cat [$w curselection]
	if { $cat == "" } { return }
	set cat [$w get $cat]
	if { $cat == ".." } { return }

	set acdir [file nativename $AC3D_HOME]
	set dir [file nativename $dir/$cat]

	if { $tcl_platform(platform) == "windows" } {
		set acdir [string tolower $acdir]
		set dir [string tolower $dir]
	}

	if { [string first $dir $acdir] == 0 } {
		tk_messageBox -title "Delete category" -message "Can't delete a parent directory of AC3D"
		return
	}

	set choice [tk_messageBox -type yesno -default no -title "Confirm delete category" -message "Are you sure you want to delete category \"$cat\"\nand all sub-categories?"]
	if { $choice == "yes" } {
		file delete $dir
		puts "Deleted category $dir"
		obj_refresh
	}
}


proc obj_change_root {} {

	global prefs_object_library_path
	global objsub
	global objdir

	set newobjroot [tk_chooseDirectory -title "Select object library root" -initialdir $prefs_object_library_path -mustexist 1 -parent .]
	if { $newobjroot == "" } { return }

	if { $newobjroot != $prefs_object_library_path } {
		set prefs_object_library_path $newobjroot
		set objsub ""
		set objdir $prefs_object_library_path
		obj_refresh
	}
}


proc obj_lib_dlg {} {

	global AC3D_HOME
	global prefs_object_library_path
	global objsub
	global objdir
	global filename_im

	if [winfo exists .ol] {
		wm deiconify .ol
		centre_window_on_screen .ol
		return
	}

	# default is for AC3D to start with empty path - use the AC3D_HOME/model dir in this case
	if { $prefs_object_library_path == "" } {
		set prefs_object_library_path "$AC3D_HOME/models"
	}

	regsub -all "\\\\" $prefs_object_library_path "/" prefs_object_library_path
	set objsub ""
	set objdir $prefs_object_library_path

	set filename_im ""

	toplevel .ol
	wm title .ol "Object library"
	wm transient .ol [winfo toplevel [winfo parent .ol]]

	labelframe .ol.root -text "Library root"
	entry .ol.root.path -textvariable prefs_object_library_path -width 50
	button .ol.root.browse -text "Browse" -command { obj_change_root }

	add_balloon .ol.root.browse "Select a new library root"

	bind .ol.root.path <Return> {
		regsub -all "\\\\" $prefs_object_library_path "/" prefs_object_library_path
		set objsub ""
		set objdir $prefs_object_library_path
		obj_refresh
	}

	frame .ol.a

	labelframe .ol.a.dir -text "Categories"
	frame .ol.a.dir.a
	listbox .ol.a.dir.a.content -height 12 -width 30 -yscrollcommand ".ol.a.dir.a.scroll set"
	scrollbar .ol.a.dir.a.scroll -orient vertical -command { .ol.a.dir.a.content yview }
	frame .ol.a.dir.b
	button .ol.a.dir.b.new -text "New..." -command { obj_new_subcat $objdir }
	button .ol.a.dir.b.del -text "Delete" -command { obj_delete_cat $objdir }
	button .ol.a.dir.b.root -text "Set root" -command { if { $objsub == "" } { return }; set prefs_object_library_path $prefs_object_library_path$objsub; set objsub ""; set objdir $prefs_object_library_path; obj_refresh }

	add_balloon .ol.a.dir.a.content "Available sub-categories"
	add_balloon .ol.a.dir.b.new "Create new category"
	add_balloon .ol.a.dir.b.del "Delete selected category"
	add_balloon .ol.a.dir.b.root "Use current category as library root"

	labelframe .ol.a.obj -text "Objects"
	frame .ol.a.obj.a
	listbox .ol.a.obj.a.content -height 12 -width 30 -yscrollcommand ".ol.a.obj.a.scroll set"
	scrollbar .ol.a.obj.a.scroll -orient vertical -command { .ol.a.obj.a.content yview }
	frame .ol.a.obj.b
	button .ol.a.obj.b.load -text "Retrieve" -command { obj_load $objdir $filename_im }
	button .ol.a.obj.b.save -text "Store..." -command { obj_save_dlg $objdir }
	button .ol.a.obj.b.replace -text "Replace..." -command { obj_save $objdir $filename_im }
	button .ol.a.obj.b.del -text "Delete" -command { obj_delete_file $objdir $filename_im }

	button .ol.close -text "Close" -command { wm withdraw .ol }

	add_balloon .ol.a.obj.a.content "Objects in current category"
	add_balloon .ol.a.obj.b.load "Retrieve selected item from library"
	add_balloon .ol.a.obj.b.save "Store current selection in object library"
	add_balloon .ol.a.obj.b.replace "Replace library item with current selection"
	add_balloon .ol.a.obj.b.del "Delete selected item from object library"

	obj_refresh

	bind .ol.a.dir.a.content <Double-Button-1> {

		if { [catch { set sel [selection get] }] } { return }

		if { $sel == ".." } {
			regsub "\[^/\]+/$" $objsub "" objsub
		} else {
			set newsub $objsub$sel
			if { [file exists $prefs_object_library_path$newsub] } {
				set objsub "$newsub/"
			}
		}
		set objdir $prefs_object_library_path$objsub
		obj_refresh
	}

	bind .ol.a.obj.a.content <Double-Button-1> {
		catch {
			set filename_im [selection get]
			obj_load $objdir $filename_im
		}
	}

	bind .ol.a.obj.a.content <ButtonRelease> {
		catch {
			set filename_im [selection get]
		}
	}

	pack .ol.root.path -side left -padx 3
	pack .ol.root.browse -side right -padx 3
	pack .ol.root -side top -anchor w -ipady 2 -padx 2 -pady 4

	pack .ol.a.dir.a.content -side left -padx {2 0}
	pack .ol.a.dir.a.scroll -side left -fill y -padx {0 2}
	pack .ol.a.dir.a -side top
	pack .ol.a.dir.b.new -side left -pady 3 -padx 2
	pack .ol.a.dir.b.del -side left -pady 3 -padx 2
	pack .ol.a.dir.b.root -side left -pady 3 -padx 2
	pack .ol.a.dir.b -side top
	pack .ol.a.dir -side left -padx 2

	pack .ol.a.obj.a.content -side left -padx {2 0}
	pack .ol.a.obj.a.scroll -side left -fill y -pady 3 -padx {0 2}
	pack .ol.a.obj.a -side top
	pack .ol.a.obj.b.load -side left -pady 3 -padx 2
	pack .ol.a.obj.b.save -side left -pady 3 -padx 2
	pack .ol.a.obj.b.replace -side left -pady 3 -padx 2
	pack .ol.a.obj.b.del -side left -pady 3 -padx 2
	pack .ol.a.obj.b -side top
	pack .ol.a.obj -side left -padx 2

	pack .ol.a -side top
	pack .ol.close -side bottom -pady 6

	centre_window_on_screen .ol
}
