#!/bin/sh
# Restart with wish\
exec wish "${0}" "${@}"

# TODO:
# - Merge into OV
# - Add balloon and nameplate
#   - Make them positionable by drag'n'drop and arrow keys
#   - Show numeric coordinates in editable panel widgets
#   - Offer checkboxes to temporarily hide each
# - Make key bindings user-configurable, VILE
# - Make .aved a toplevel
# - Fix size of panel to fit a set number of frames across platforms
# - Offer a different look for Windows
# - Actually copy images to the user's images directory
# - Provide load and save capability
# - Do translations
# - Make preview background colors configurable
# WISHLIST:
# - Offer a hierarchial avatar menu
# - Offer avatar thumbnails

source ov-share.tcl
lappend auto_path [file nativename "[pwd]/BWidget-1.3.1"]
package require BWidget

set MV(homedir) "~/.OpenVerse"

# Load images
image create photo "img::up" -file "up.gif"
image create photo "img::down" -file "down.gif"
image create photo "img::new" -file "new.gif"
image create photo "img::del" -file "del.gif"
image create photo "img::browse" -file "browse.gif"
image create photo "img::hand" -file "hand.gif"
image create photo "img::yes" -file "yes.gif"
image create photo "img::no" -file "no.gif"
image create photo "img::play" -file "play.gif"
image create photo "img::pause" -file "pause.gif"
image create photo "img::file_not_found" -file "file_not_found.gif"
image create photo "img::bad_file" -file "bad_file.gif"

# TODO: make this user-configurable, VILE; do this at OV start
event add <<AvEd-Browse>> <Control-o> <Control-O>
event add <<AvEd-Prev>> <Key-Prior>
event add <<AvEd-Next>> <Key-Next>
#event add <<AvEd-First>>
#event add <<AvEd-Last>>
#event add <<AvEd-PgUp>>
#event add <<AvEd-PgDn>>
event add <<AvEd-New>> <Key-Return>
event add <<AvEd-Del>> <Control-Delete>

namespace eval aved {
variable num_frames 0	;# Number of frames in current animation
variable sel_frame 0	;# Index of currently selected frame
variable scroll_idx 0	;# Index of first onscreen frame in list
variable vis_frames 7	;# Number of onscreen frames in list
variable frames		;# Dynamic array of frame information
variable animated 0	;# Is this avatar animated?
variable bg_color 0	;# Index of preview color in use
variable next_image 0	;# Counter for next preview image to create
variable playback 0	;# Is the avatar being played right now?
variable playback_id	;# After id for playback process

variable balloon 0	;# Is the balloon being shown?
variable balloon_x 0	;# X coordinate of speech balloon
variable balloon_y 0	;# Y coordinate of speech balloon

variable name 0		;# Is the nameplate being shown?
variable name_x 0	;# X coordinate of nameplate
variable name_y 0	;# Y coordinate of nameplate

# Default path for loading avatar images
variable default_path [file nativename "$MV(homedir)/images"]

# List of colors to use for avatar preview background
variable colors {"gray" "black" "white" "navy"}

# --- ANIMATION EDITOR --------------------------------------------------------
# Highlight frame $idx with $color
proc set_frame_color {idx color} {
	foreach elem {".hand" ".num" ".img" ".dur" ".ms" ""} {
		.aved.anim.${idx}$elem configure -bg $color
	}
}

# Show selection (or lack thereof, depending on $flag) for frame $idx
proc show_selection {idx flag} {
	variable sel_frame

	# This uses a dirty hack to hide or show the hand...
	set tmp $sel_frame
	if $flag {
		set sel_frame $idx
		verify_image $idx -trust-cache
		set_frame_color $idx lightblue
	} else {
		set sel_frame -1
		verify_image $idx -trust-cache
		set_frame_color $idx gray
	}
	set sel_frame $tmp
}

# Make $idx the active frame
proc select_frame {idx args} {
	variable num_frames
	variable frames
	variable scroll_idx
	variable sel_frame

	# Clip $idx to available frames
	if {$idx < 0} {
		set idx 0
	} elseif {$idx >= $num_frames} {
		set idx [expr $num_frames - 1]
	}

	# Scroll to the frame if necessary
	scroll_to $idx
	
	# Adjust focus (focus handler will do the rest)
	set cur_focus [focus -displayof .]
	if [string match ".aved.anim.*" $cur_focus] {
		set part [string range $cur_focus [expr [string last .\
				$cur_focus] + 1] end]
	} else {
		set part "img"
	}
	if {[string_equal ".aved.anim.$sel_frame.$part" $cur_focus] &&
			[string match [lindex $args 0] "-force"]} {
		handle_focus $idx
	} else {
		focus .aved.anim.$idx.$part
	}
}

# Handle focus on frame in visible slot $idx
proc handle_focus {idx} {
	variable num_frames
	variable sel_frame
	variable scroll_idx
	variable vis_frames
	variable frames

	# Update preview image
	verify_image $idx -vcmd $frames($idx.img)

	# Adjust colors and hand icon for current and previous frames
	if {$sel_frame != $idx} {
		if {$sel_frame < $num_frames} {show_selection $sel_frame 0}
		show_selection $idx 1
		set sel_frame $idx
	}
}

# Add a new frame widget to the list
proc create_frame_widget {idx} {
	variable sel_frame

	# Create the gui elements
	set path .aved.anim.$idx
	frame $path -bd 1 -relief sunken
	label $path.hand -bd 0 -width 0
	entry $path.img -highlightthickness 0 -bd 0 -width 1 -validate key\
			-vcmd "aved::verify_image $idx -vcmd %P" -textvariable\
			"aved::frames($idx.img)"
	entry $path.dur -highlightthickness 0 -bd 0 -width 5 -justify right\
			-textvariable "aved::frames($idx.dur)" -vcmd\
			"aved::set_button_states %P" -validate key
	label $path.num -bd 0 -justify right -width 0 -text "[expr $idx + 1]."\
			-font [$path.img cget -font]
	label $path.ms -bd 0 -text "ms" -width 2 -font [$path.img cget -font]
	bind $path <FocusIn> "aved::handle_focus $idx"
	show_selection $idx [expr $idx == $sel_frame]
	verify_image $idx -trust-cache

	# Put together the frame
	pack $path.hand $path.num -side left
	pack $path.img -side left -fill x -expand 1
	pack $path.dur $path.ms -side left

	# Pack it
	if {$idx == 0} {
		pack $path -fill x
	} else {
		pack $path -fill x -after .aved.anim.[expr $idx - 1]
	}
}

# Insert a new frame immediately after active frame
# Also used to initialize the very first frame
proc new_frame {args} {
	variable num_frames
	variable sel_frame
	variable frames
	variable scroll_idx
	variable vis_frames
	variable next_image
	variable animated

	if [string_equal $args "-init"] {
		set idx 0
		set frames($idx.dur) 100
	} else {
		set idx [expr $sel_frame + 1]
		for {set i $num_frames} {$i > $idx} {incr i -1} {
			set j [expr $i - 1]
			foreach elem {"img" "dur" "good" "img_id"} {
				set frames($i.$elem) $frames($j.$elem)
			}
			if {$i < $num_frames} {verify_image $i -trust-cache}
		}
		set frames($idx.dur) $frames($sel_frame.dur)
	}
	set frames($idx.img) ""
	set frames($idx.good) 0
	set frames($idx.img_id) "img::aved::$next_image"
	image create photo $frames($idx.img_id)
	incr next_image
	incr num_frames

	# Create, configure, and pack the gui elements as needed
	if $animated {
		create_frame_widget [expr $num_frames - 1]
		select_frame $idx
	}
}

# Delete active frame
proc del_frame {} {
	variable num_frames
	variable sel_frame
	variable frames

	if {$num_frames == 1} {return}

	# Shift frames back to cover deleted one
	set img $frames($sel_frame.img_id)
	for {set i $sel_frame} {$i < [expr $num_frames - 1]} {incr i} {
		set j [expr $i + 1]
		foreach elem {"img" "dur" "good" "img_id"} {
			set frames($i.$elem) $frames($j.$elem)
		}
		verify_image $i -trust-cache
	}

	# Destroy final frame widget and the no-longer-needed image
	destroy .aved.anim.[expr $num_frames - 1]
	image delete $img
	
	# Remove array entry for final frame
	incr num_frames -1
	array unset frames "$num_frames.*"

	# Highlight new current frame
	select_frame $sel_frame -force
}

# Swap the active frame and its $adj'th neighbor
proc move_frame {adj} {
	variable num_frames
	variable sel_frame
	variable frames

	set j [expr $sel_frame + $adj]
	if {$j < 0 || $j >= $num_frames} {return}

	foreach elem {"img" "dur" "img_id"} {
		swap frames($sel_frame.$elem) frames($j.$elem)
	}

	select_frame $j
}

# Display frame $idx
proc scroll_to {idx args} {
	variable num_frames
	variable vis_frames
	variable scroll_idx
	set do_scroll 1
	if [string_equal $args "-abs"] {set abs 1} else {set abs 0}

	# Keep $idx in range
	if {$idx < 0} {
		set idx 0
	} elseif $abs {
		if {$num_frames >= $vis_frames} {
			if [expr $idx > $num_frames - $vis_frames &&\
					$num_frames >= $vis_frames] {
				set idx [expr $num_frames - $vis_frames]
			}
		} else {
			set idx 0
		}
	} elseif {$idx >= $num_frames} {
		set idx [expr $num_frames - 1]
	}

	# Is this frame already visible?
	if $abs {
		if {$scroll_idx == $idx} {set do_scroll 0}
	} else {
		if [expr $idx >= $scroll_idx && $idx < $scroll_idx +\
				$vis_frames] {
			if [expr $scroll_idx + $vis_frames > $num_frames &&\
					$num_frames >= $vis_frames] {
				# Eliminate dead space at end of list
				set idx [expr $num_frames - $vis_frames]
			} else {
				set do_scroll 0
			}
		}
	}

	if $do_scroll {
		# Calculate some stuff
		if {$idx < $scroll_idx} {
			# Scroll up
			set add [expr $scroll_idx - 1]
			set del [expr $scroll_idx + $vis_frames - 1]
			set count [expr $scroll_idx - $idx]
			set scroll_idx $idx
			set adj -1
			set offset "-before"
		} else {
			# Scroll down
			set add [expr $scroll_idx + $vis_frames]
			set del $scroll_idx
			if $abs {
				set count [expr $idx - $scroll_idx]
				set scroll_idx $idx
			} else {
				set count [expr 1 + $idx - $scroll_idx -\
						$vis_frames]
				set scroll_idx [expr $idx - $vis_frames + 1]
			}
			set adj 1
			set offset "-after"
		}
		# Scroll one frame at a time
		for {set i 0} {$i < $count} {incr i} {
			pack forget .aved.anim.$del
			pack .aved.anim.$add -fill x\
					$offset .aved.anim.[expr $add - $adj]
			incr del $adj
			incr add $adj
		}
	}
	# Fix the scrollbar
	.aved.scroll set [expr $scroll_idx / ${num_frames}.0]\
			[expr ($scroll_idx + $vis_frames) / ${num_frames}.0]
}

# Handle scrollbar movement
proc scroll {args} {
	variable num_frames
	variable scroll_idx
	variable vis_frames

	switch -- [lindex $args 0] {
	"moveto" {
		scroll_to [expr int($num_frames * [lindex $args 1])] -abs
	} "scroll" {
		set adj [lindex $args 1]
		switch -- [lindex $args 2] {
		"pages" {
			scroll_to [expr $scroll_idx + $adj * $vis_frames] -abs
		} "units" {
			scroll_to [expr $scroll_idx + $adj] -abs
		}}
	}}
}

# Start or stop playback of animation
proc toggle_play {} {
	variable sel_frame
	variable playback
	variable playback_id
	variable frames

	if $playback {
		set playback 0
		.aved.funcs.anim.play configure -image "img::play"
		after cancel $playback_id
		.aved.preview itemconfigure img -image\
				$frames($sel_frame.img_id)
	} else {
		set playback 1
		.aved.funcs.anim.play configure -image "img::pause"
		next_frame 0
	}
}

# Go to the next frame of an animation
proc next_frame {idx} {
	variable frames
	variable playback_id
	variable num_frames
	
	# Show current frame
	if {$idx >= $num_frames} {set idx 0}
	.aved.preview itemconfigure img -image $frames($idx.img_id)
	update

	# Arrage for next frame to be shown
	set playback_id [after $frames($idx.dur) "aved::next_frame\
			[expr $idx + 1]"]
}

# Create the animation panel
proc create_anim_panel {} {
	variable frames

	frame .aved.funcs.anim
	frame .aved.funcs.anim.buttons
	foreach {elem func} {"up" "move_frame -1" "down" "move_frame 1" 
			"new" "new_frame" "del" "del_frame"
			"browse" "pick_image" "play" "toggle_play"} {
		button .aved.funcs.anim.$elem -image "img::$elem" -bd 1\
				-highlightthickness 0 -command "aved::$func"
		pack .aved.funcs.anim.$elem -in .aved.funcs.anim.buttons\
				-side top -fill y -expand 1
	}
	scrollbar .aved.scroll -highlightthickness 0 -bd 0 -relief flat\
			-orient vertical -command {aved::scroll}\
			-elementborderwidth 1
	pack .aved.scroll -in .aved.funcs.anim -side left -fill y
	pack .aved.funcs.anim.buttons -side right -fill y -expand 1
	frame .aved.anim
	create_frame_widget 0
}

# Display the animation editor panel
proc show_anim_panel {} {
	pack .aved.funcs.anim -side left -fill y
	pack .aved.anim -in .aved.edit -side left -expand 1 -fill both

	select_frame 0

	# Some key bindings...
	# TODO: make these bind .aved
	bind . <<AvEd-Prev>> {aved::select_frame [expr $aved::sel_frame - 1]}
	bind . <<AvEd-Next>> {aved::select_frame [expr $aved::sel_frame + 1]}
	bind . <<AvEd-First>> {aved::select_frame 0}
	bind . <<AvEd-Last>> {aved::select_frame [expr $aved::num_frames - 1]}
	bind . <<AvEd-PgUp>> {aved::scroll scroll -1 pages}
	bind . <<AvEd-PgDn>> {aved::scroll scroll 1 pages}
	bind . <<AvEd-New>> {aved::new_frame}
	bind . <<AvEd-Del>> {aved::del_frame}
	foreach ev {"Prev" "Next" "First" "Last" "PgUp" "PgDn" "New" "Del"} {
		bind . <<AvEd-$ev>> +break
	}
}

# Hide the animaion panel
proc hide_anim_panel {} {
	variable sel_frame
	variable scroll_idx
	variable num_frames
	variable vis_frames
	variable playback

	if $playback {toggle_play}

	pack forget .aved.funcs.anim
	pack forget .aved.anim

	foreach ev {"Prev" "Next" "First" "Last" "PgUp" "PgDn" "New" "Del"} {
		bind . <<AvEd-$ev>>
	}
}

# --- STILL EDITOR ------------------------------------------------------------
# Create still avatar editor panel
proc create_still_panel {} {
	frame .aved.still
	label .aved.still.image -text "GIF Filename:"
	frame .aved.still.edit -bd 1 -relief sunken
	entry .aved.still.edit.img -highlightthickness 0 -bd 0\
			-textvariable "aved::frames(0.img)" -validate key\
			-vcmd "aved::verify_image 0 -vcmd %P" 
	button .aved.still.edit.browse -image "img::browse" -bd 1\
			-highlightthickness 0 -command "aved::pick_image"
	pack .aved.still.edit.img -side left -fill both -expand 1
	pack .aved.still.edit.browse -side right
	pack .aved.still.image .aved.still.edit -fill x -expand 1
}

# Display the still panel
proc show_still_panel {} {
	pack .aved.still -in .aved.edit -fill x -expand 1
	bind . <<AvEd-Browse>> {aved::pick_image; break}
	focus .aved.still.edit.img
	.aved.still.edit.img icursor end
}

# Hide the still panel
proc hide_still_panel {} {
	pack forget .aved.still
	bind . <<AvEd-Browse>>
}

# --- COMMON ------------------------------------------------------------------
# Create common AvEd panel
# TODO: offer a slightly different look tailored for Windows
# (make this a global OV setting, perhaps, along with colors 'n stuff)
proc create_common_panel {} {
	variable colors
	variable bg_color

	# Background colors
	frame .aved.bg
	label .aved.bg.bg -text "BG:" -bd 0
	pack .aved.bg.bg -side left -fill x -expand 1
	set i 0
	foreach {name} $colors {
		radiobutton .aved.bg.$name -text [string totitle $name]\
				-command "aved::set_background" -value $i\
				-variable "aved::bg_color" -bd 1
		pack .aved.bg.$name -side left -fill x -expand 1
		incr i
	}

	# Preview canvas
	frame .aved.pframe -bd 1 -relief sunken
	canvas .aved.preview -highlightthickness 0 -bd 0 -width 0 -height 0
	.aved.preview create image 0 0 -tag img
	set_background
	bind .aved.preview <Configure> "aved::adjust_preview"
	pack .aved.preview -in .aved.pframe -fill both -expand 1

	# Editor pane
	# TODO: fix this filthy hack with the widget pady stuff
	frame .aved.edit -height 108
	frame .aved.overlay -bd 1 -relief sunken
	foreach elem {"Balloon" "Name"} {
		set var "aved::[string tolower $elem]"
		set path ".aved.overlay.[string tolower $elem]"
		frame $path -bd 1 -relief raised
		frame $path.f
		checkbutton $path.b -text $elem -variable $var -bd 1
		label $path.l -text "("
		entry $path.x -textvariable "${var}_x" -width 3 -bd 0\
				-highlightthickness 0 -justify right
		label $path.c -text ","
		entry $path.y -textvariable "${var}_y" -width 3 -bd 0\
				-highlightthickness 0 -justify right
		label $path.r -text ")"
		foreach elem2 {"b" "l" "x" "c" "y" "r"} {
			pack $path.$elem2 -in $path.f -side left
		}
		pack $path.f -expand 1
		pack $path -side left -fill x -expand 1
	}
	pack .aved.overlay -in .aved.edit -fill x -expand 1
	frame .aved.funcs -bd 1 -relief sunken
	frame .aved.buttons
	foreach {type name func} {
			"button" "load" ""
			"button" "save" ""
			"button" "close" "exit"
			"checkbutton" "anim" "aved::toggle_anim"} {
		$type .aved.buttons.$name -text [string totitle $name]\
			-command $func -highlightthickness -0 -bd 1\
			-padx 4 -pady 8
		pack .aved.buttons.$name -side top -fill both -expand 1
	}
	.aved.buttons.anim configure -pady 3
	.aved.buttons.anim configure -variable "aved::animated"
	pack .aved.buttons -in .aved.funcs -side right -fill y
	pack .aved.funcs -in .aved.edit -side right -fill y
}

# Show the common parts of the avatar editor panel
proc show_common_panel {} {
	variable frames
	variable sel_frame

	.aved.preview itemconfigure img -image $frames($sel_frame.img_id)
	pack .aved.bg -fill x
	pack .aved.pframe -fill both -expand 1
	pack .aved.edit -fill x
}

# Switch between still and animated avatar mode
proc toggle_anim {} {
	variable animated
	variable frames
	if $animated {
		hide_still_panel
		show_anim_panel
	} else {
		select_frame 0
		hide_anim_panel
		show_still_panel
	}
}

# Change the color of the preview canvas
proc set_background {} {
	variable bg_color
	variable colors

	.aved.preview configure -bg [lindex $colors $bg_color]
}

# Relocate the preview contents to be in the canvas center
# TODO: move balloon and nameplate
proc adjust_preview {} {
	set x1 [lindex [.aved.preview coords img] 0]
	set y1 [lindex [.aved.preview coords img] 1]
	set x2 [expr [winfo width .aved.preview] / 2]
	set y2 [expr [winfo height .aved.preview] / 2]
	.aved.preview move img [expr $x2 - $x1] [expr $y2 - $y1]
}

# Allow user to pick a file from a browser; save as active frame
proc pick_image {} {
	variable sel_frame
	variable frames
	variable default_path
	variable animated

	set file [tk_getOpenFile -initialdir $default_path -filetypes {
			{"GIF Image Files"	{.gif .GIF .Gif}}
			{"GIF Image Files"	{}	"GIFF"	}
			{"All Files"		*		}}]

	if ![string length $file] {return}

	# Replace spaces with underscores
	set newname [string_map {" " "_"} [file tail $file]]
	
	# TODO: enable this
	# Copy the selected file to the user's images directory, if necessary
	#if {![file exists "$MV(homedir)/images/$newname"] ||
	#		[file size "$MV(homedir)/images/$newname"] !=
	#		[file size $file]} {
	#	file copy -force $file "$MV(homedir)/images/$newname"
	#}

	set default_path [file dirname $file]

	set frames($sel_frame.img) $newname
	if $animated {
		set widget ".aved.anim.$sel_frame.img"
	} else {
		set widget ".aved.still.edit.img"
	}
	focus $widget
	$widget icursor end
}

# Checks the "good" cache to determine whether to enable save and playback
proc set_button_states {args} {
	variable frames
	variable num_frames
	variable sel_frame
	variable animated
	variable playback

	set save_state "normal"
	for {set idx 0} {$idx < $num_frames} {incr idx} {
		if {$frames($idx.good) != 3} {
			set save_state "disabled"
			break
		}
	}
	if $animated {
		if [llength $args] {
			if {[string is digit -strict [lindex $args 0]] &&
					[lindex $args 0] >= 10} {
				set test "\$idx != $sel_frame &&\
						\$frames(\$idx.dur) < 1"
			} else {
				set test "\$idx == $sel_frame ||\
						\$frames(\$idx.dur) < 1"
			}
		} else {
			set test "\$frames(\$idx.dur) < 1"
		}

		set anim_state "normal"
		for {set idx 0} {$idx < $num_frames} {incr idx} {
			if $test {
				set save_state "disabled"
				set anim_state "disabled"
				break
			}
		}
		if {$playback && [string_equal $anim_state "disabled"]} {
			toggle_play
		}
		.aved.funcs.anim.play configure -state $anim_state
	}
	.aved.buttons.save configure -state $save_state

	if [llength $args] {return [string is digit [lindex $args 0]]}
}

# Verifies $idx's vailidity and sets its hand element to reflect
proc verify_image {idx args} {
	global MV
	variable sel_frame
	variable frames
	variable playback
	variable num_frames

	set update_cache 1
	set vcmd 0

	# Handle arguments
	if [llength $args] {
		switch -- [lindex $args 0] {
		case "-trust-cache" {
			set update_cache 0
		} case "-vcmd" {
			set vcmd 1
		}}
	}

	# Determine a "good" value to cache, or just use the old value?
	# "good" values: 0: no name; 1: file not found; 2: bad file; 3: success
	if $update_cache {
		# Determine image filename
		if $vcmd {
			set orig_name [lindex $args 1]
		} else {
			set orig_name $frames($idx.img)
		}
		set name "$MV(homedir)/images/[string_map {" " "_"} $orig_name]"

		if $vcmd {
			# Assumption: in vcmd mode, idx == sel_frame
			# Therefore, modify frame image
			set good [load_image $idx $name $orig_name]
		} else {
			# Assumption: when not in vcmd mode, idx != sel_frame
			# except to initially show the hand and frame images
			# Therefore, modify the hand
			if {[string_equal -nocase [file extension $name]\
					".gif"] && [file readable $name]} {
				set good 3
			} elseif ![string length $orig_name] {
				set good 0
			} else {
				set good 1
			}
		}
	}
	set frames($idx.good) $good
	
	# Now make use of the cached information
	if !$vcmd {
		# Nothing more to do for vcmd mode...
		if {$idx == $sel_frame} {
			set img "img::hand"
			if !$playback {
				.aved.preview itemconfigure img -image\
						$frames($idx.img_id)
			}
		} elseif {$frames($idx.good) == 3} {
			set img "img::yes"
		} else {
			set img "img::no"
		}
		.aved.anim.$idx.hand configure -image $img
	}

	# Enable or disable the save and playback buttons
	set_button_states

	if $vcmd {
		# Appease the calling entry field
		return 1
	}
}

# Attempt to load an image from disk; return a "good" value
proc load_image {idx name orig_name} {
	variable frames
	if [string length $orig_name] {
		if [file readable $name] {
			$frames($idx.img_id) blank
			if {![string_equal -nocase [file extension $name]\
					".gif"] || [catch "$frames($idx.img_id)\
					read $name -shrink"]} {
				$frames($idx.img_id) copy "img::bad_file"\
						-shrink
				return 2
			}
			return 3
		} else {
			$frames($idx.img_id) copy "img::file_not_found" -shrink
			return 1
		}
	} else {
		$frames($idx.img_id) blank
		return 0
	}
}

# Main AvEd procedure
proc main {} {
	# TODO: make .aved a toplevel, not a frame
	wm title . "OpenVerse Avatar Editor"
	wm resizable . 1 1
	wm minsize . 300 330
	frame .aved

	#new_frame -init
	#create_common_panel
	#create_still_panel
	#create_anim_panel

	#show_still_panel
	#show_common_panel

	#pack .aved -expand 1 -fill both

	frame .colors
	frame .preview -relief sunken -bd 1
	frame .edit
	PanedWindow .div -side left
	set path [.div add]
	pack .colors -in $path -side top -fill x
	pack .preview -in $path -side bottom -fill both -expand 1
	set path [.div add]
	pack .edit -in $path -fill both -expand 1
	pack .div -fill both -expand 1
	update

#	balloon::do_balloon 40 40 .aved.preview balloon -text "Hello!"
}
}

aved::main

