# Copyright (c) 2000, Red Hat, Inc.
# 
# This file is part of Source-Navigator.
# 
# Source-Navigator is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 2, or (at your option)
# any later version.
# 
# Source-Navigator is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# You should have received a copy of the GNU General Public License along
# with Source-Navigator; see the file COPYING.  If not, write to
# the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
# 
################################################
##
## Configure Build Rule Dialog for SN-IDE.
## Copyright (c) 1999 Cygnus Solutions, Inc.
## Written by Ian Roxborough <irox@cygnus.com>
##
################################################

itcl_class snIdeToolsDlg {

#    method CreateDialog {}
#    method FlagPage {container}
    method test {} {
        if {[info objects $toolchain]!=""} {
            puts "It's A-OK"
        } else {
            puts "Tool chain $toolchain does not exist"
        }
    }
    public toolchain ""
    public ruleSuffix ""
    public ruleType ""
    protected b_target ""

    # The dialog window path.
    protected dlgwin ""
    
    protected focus "" ; #Last focus before create dialog.

    protected okbutt "" ; # The OK button.

    protected debugLookUp    ;# Array to lookup string tags
    protected optimizeLookUp ;# Array ...
    protected warnLookUp     ;# Array ...
    protected codeLookUp     ;# Array ...

    # flags widgets:
    protected debugLBX ""
    protected optimizeLBX ""
    protected warnLBX ""
    protected codeLBX ""
    protected exeLEB ""
    protected uflagsENT ""
    protected cmdlTXT ""

    # includes widgets:
    protected AutoGenList ""
    protected UserGenList ""

    # define buttons/widgets
    protected DefNewButt ""
    protected DefDelButt ""
    protected DefSetButt ""
    protected UserDefsList ""
    protected EditDef ""

    method constructor {tool_chain rule build_target {args ""}} {

        set toolchain $tool_chain
        set ruleType $rule
        set b_target $build_target
        set RuleSuffix "TODO: get rule suffix"
        #TODO: check tool_chain, rule and build_target are valid
    }

    method CreateDialog {} {
        global tkPriv
        #TODO: CheckToolChain
        #TODO: CheckRuleType

        set tail "tail"
        set dlgwin $this$tail
        toplevel $dlgwin

        set finfo [$toolchain GetFileInfo $ruleType]
        wm title $dlgwin "[get_indep String IDEBuildRuleTitle] \[$finfo\]"

	set focus [focus]
	if {$focus == ""} {
            set focus "."
	} else {
            set focus [winfo toplevel $focus]
	}
	if {[wm state $focus] == "normal"} {
	    wm transient $dlgwin $focus
	}

        #create notebook widget
        set notebook [tixNoteBook $dlgwin.nb]

        #Add a leaf for Settings/flags.
        set flagsleaf [$notebook add flags -label [get_indep String IDEBRSettingsTab] -under [get_indep Pos IDEBRSettingsTab]]
        FlagPage $flagsleaf

        #Add a leaf for Incudes Files.
        set includesleaf [$notebook add includes -label [get_indep String IDEBRIncludesTab] -under [get_indep Pos IDEBRIncludesTab]]
        IncludesPage $includesleaf

        #Add a leaf for macro defines.
        set definesleaf [$notebook add defines -label [get_indep String IDEBRDefinesTab] -under [get_indep Pos IDEBRDefinesTab]]
        DefinesPage $definesleaf

        pack $notebook -pady 6 -padx 6

        # Add OK and Cancel buttons.
        set okbutt [button $dlgwin.ok -text [get_indep String IDEBROK] -width 11 -command "$this ok_cb"]
        set cancelbutt [button $dlgwin.canit -text [get_indep String IDEBRCancel] -width 11 -command "$this cancel_cb"]

        # bind Escape and Close Window button to Cancel
	wm protocol $dlgwin WM_DELETE_WINDOW "$cancelbutt invoke"
	bind $dlgwin <Escape> "$cancelbutt invoke"

        pack $cancelbutt $okbutt -pady 6 -padx 6 -side right	

        InitializeFlagData
	UpdateCommandLineArguements dumy dumy

	# Make the dialog modal	
        grab_focus
	bind_focus_enter $dlgwin {catch {focus %W}}

	catch {$dlgwin resizable yes no}
        grab_focus
	focus $dlgwin
	#update idletasks
	#set geom [split [lindex [split [$w geometry] "+"] 0] "x"]
	#$w minsize [lindex $geom 0] [lindex $geom 1]
	
#	$dlgwin move_to_mouse
#	$dlgwin take_focus $w.button_0

	tkwait variable tkPriv($dlgwin,button)

	DestroyDialog

	catch {focus $focus}
        $this delete
    }

    method grab_focus {} {
        global tcl_platform
	
	set old_grab [lindex [@@grab current] 0]
	bind $dlgwin <1> \
				"if {\"%W\" == \"$dlgwin\"} {
			        
				    set wdg [@@focus -lastfor $dlgwin]
				    eval focus -force $dlgwin
				    focus \$wdg
			        
			        raise $dlgwin
				bell -displayof %W
				}
				break
				"
	bind $dlgwin <2> [bind $dlgwin <1>]
	bind $dlgwin <3> [bind $dlgwin <1>]
	grab set $dlgwin
    }

    method FlagPage {container} {

        global FlagTags

        # TODO: check optimizations, debug, warnings, code generation.

        set optIDTagList [$toolchain GetRuleFlagsIDTagsList $ruleType Optimize]
        set debugIDTagList [$toolchain GetRuleFlagsIDTagsList $ruleType Debug]
        set warnIDTagList [$toolchain GetRuleFlagsIDTagsList $ruleType Warning]
        set codeGenIDTagList [$toolchain GetRuleFlagsIDTagsList $ruleType CodeGen]

        #
        # Create debug flag list
        #

        set debugLBX [combobox::combobox $container.dbglbx -command "$this cb_combobox_changed"]
        set debugLBL [label $container.dbglbl -text [get_indep String IDEBRDebugCombo]]

        if {$debugIDTagList == "" } {
            #disable debug listbox if no flags
            $debugLBX configure -state disabled
        } else {
            foreach debugIDTag $debugIDTagList {
                set debugLookUp($FlagTags($debugIDTag)) $debugIDTag
                set tmpCmd "$debugLBX listinsert end \"$FlagTags($debugIDTag)\""
                eval $tmpCmd
            }
            $debugLBX configure -editable 0
        }
        grid $debugLBL -column 1 -row 2 -sticky e
        grid $debugLBX -column 2 -row 2

        #
        # Create optimizations list of flags
        #

        set optimizeLBL [label $container.optlbl -text [get_indep String IDEBROptimizationCombo]]
        set optimizeLBX [combobox::combobox $container.optlbx \
	                -command "$this cb_combobox_changed"]

        if {$optIDTagList == "" } {
            #disable Optimizations listbox if not flags
            $optimizeLBX configure -state disabled
        } else {
            foreach optIDTag $optIDTagList {
                set optimizeLookUp($FlagTags($optIDTag)) $optIDTag
                set tmpCmd "$optimizeLBX listinsert end \"$FlagTags($optIDTag)\""
                eval $tmpCmd
            }
            $optimizeLBX configure -editable 0
        }
    
        grid columnconfigure $container 0 -minsize 10
        grid columnconfigure $container 3 -minsize 10
        grid columnconfigure $container 6 -minsize 10

        grid $optimizeLBL -column 4 -row 2 -sticky e
        grid $optimizeLBX -column 5 -row 2 -sticky we

        grid rowconfigure $container 1 -minsize 10
        grid rowconfigure $container 3 -minsize 10

        #
        # Create warnings flag list
        #

        set warnLBX [combobox::combobox $container.warnlbx \
	                -command "$this cb_combobox_changed"]
        set warnLBL [label $container.warnlbl -text [get_indep String IDEBRWarningCombo]]

        if {$warnIDTagList == "" } {
            #disable warnings listbox if no flags
            $warnLBX configure -state disabled
        } else {
            foreach warnIDTag $warnIDTagList {
                set warnLookUp($FlagTags($warnIDTag)) $warnIDTag
                set tmpCmd "$warnLBX listinsert end \"$FlagTags($warnIDTag)\""
                eval $tmpCmd
            }
            $warnLBX configure -editable 0
        }
        grid $warnLBL -column 1 -row 4 -sticky e
        grid $warnLBX -column 2 -row 4 -sticky we

        grid rowconfigure $container 5 -minsize 10

        #
        # Create Code Generation flag list
        #

        set codeLBX [combobox::combobox $container.codelbx \
	                -command "$this cb_combobox_changed"]
        set codeLBL [label $container.codelbl -text [get_indep String IDEBRCodeGenCombo]]

        if {$codeGenIDTagList == "" } {
            #disable debug listbox if no flags
            $codeLBX configure -state disabled
        } else {
            foreach codeGenIDTag $codeGenIDTagList {
                set codeLookUp($FlagTags($codeGenIDTag)) $codeGenIDTag
                set tmpCmd "$codeLBX listinsert end \"$FlagTags($codeGenIDTag)\""
                eval $tmpCmd
            }
            $codeLBX configure -editable 0
        }
        grid $codeLBL -column 4 -row 4 -sticky e
        grid $codeLBX -column 5 -row 4 -sticky we

        #
        # create user flags entry
        #

        set uflagsLBL [label $container.uflbl -text [get_indep String IDEBRUserFlags]]
        set uflagsENT [entry $container.ufent -textvar userflags]
	bind $uflagsENT <KeyRelease> "$this cb_combobox_changed"

        grid $uflagsLBL -column 1 -row 6 -sticky e
        grid $uflagsENT -column 2 -row 6 -sticky we

        #
        # create executable location
        #

        set exeLBL [label $container.exelbl -text [get_indep String IDEBRExecLocation]]
        set exeLEB [LabelEntryButton& $container.exeleb -text ""]
	bind $exeLEB.txt <KeyRelease> "$this cb_combobox_changed"

        grid $exeLBL -column 4 -row 6 -sticky e
        grid $exeLEB -column 5 -row 6 -sticky we

        grid rowconfigure $container 7 -minsize 10

        #
        # Create text widget to display compiler command line flags
        #

        set cmdlTXT [text $container.cmdltxt -height 3 -width 10]

        grid $cmdlTXT -column 1 -columnspan 5 -row 8 -sticky we

        grid rowconfigure $container 9 -minsize 10

	# Update the Compiler Command Line when the user does something.
	bind $container <ButtonRelease> "$this UpdateCommandLineArguements"
	bind $container <KeyRelease> "$this UpdateCommandLineArguements"

    }
    
    method cb_combobox_changed {{dumy1 ""} {dumy2 ""}} {
    
            # Update the cmd line display to reflex new settings.
            UpdateCommandLineArguements
	    
	    # since we've call the combobox the
	    # modal state won't be effective any more.
	    # so set it again.
	    grab_focus
    }

    method UpdateCommandLineArguements {{dummy1 ""} {dummy2 ""}} {
    
	set cmdline [GetCompilerCommandLine]

	# clear widget
	$cmdlTXT configure -state normal
	$cmdlTXT delete 0.0 end

	$cmdlTXT insert end $cmdline
	# Stop people editting it.
	$cmdlTXT configure -state disabled

    }

    method GetCompilerCommandLine {} {

        # Get the tool
	set tool [$exeLEB.txt get]
	if {$tool==""} {
	    set tool [$toolchain GetTool $ruleType]
	}

        # Get the basic action
	set basicaction [$toolchain GetBasicAction $ruleType]

	# Get the flags
	set flags ""
	set flags "$flags [$toolchain GetRuleFlags $ruleType Debug $debugLookUp([$debugLBX get])]"
	set flags "$flags [$toolchain GetRuleFlags $ruleType Optimize $optimizeLookUp([$optimizeLBX get])]"
	set flags "$flags [$toolchain GetRuleFlags $ruleType Warning $warnLookUp([$warnLBX get])]"
	set flags "$flags [$toolchain GetRuleFlags $ruleType CodeGen $codeLookUp([$codeLBX get])]"

	# Get user flags
	set userflags [$uflagsENT get]

	# Get the marco defs
	set defines_list [$UserDefsList get 0 end]
	set defines_spec [$toolchain FormatDefines $ruleType $defines_list]

	# Get the include paths
	set includes_list1 [$AutoGenList get 0 end]
	set includes_list2 [$UserGenList get 0 end]
	set includes_list [concat $includes_list1 $includes_list2]
	set include_spec [$toolchain FormatIncludes $ruleType $includes_list]

	return "$tool $basicaction $flags $userflags $defines_spec $include_spec"
    }

    method InitializeFlagData {} {

        SetDebugFlags
        SetWarningFlags
        SetOptimizationFlags
        SetCodeGenerationFlags

        SetUserFlags
        SetCompilerLocation

        # Includes tab
        SetGeneratedIncludes
	SetUserIncludes

        # Defines tab
        SetDefinesList
    }

    method SetDebugFlags {{flags ""}} {
        global FlagTags
        if {$flags==""} {
            #Let check the build object
            set flags [$b_target GetToolChainFlags $ruleType Debug]
        } else {
            set flags [$b_target SetToolChainFlags $ruleType Debug $flags]
        }
        
        if {$flags==""} {
            # Select the first one in the list as default
            combobox::select $debugLBX 0
        } else {
            #set it to editable first
            $debugLBX configure -editable 1
            #Delete current selection
            $debugLBX delete 0 end
            #Add stored selection
            $debugLBX insert 0 "$FlagTags($flags)"
            #Disable edit again
            $debugLBX configure -editable 0

        }
    }

    method SetWarningFlags {{flags ""}} {
        global FlagTags
        if {$flags==""} {
            #Let check the build object
            set flags [$b_target GetToolChainFlags $ruleType Warning]
        } else {
            set flags [$b_target SetToolChainFlags $ruleType Warning $flags]
        }
    
        if {$flags==""} {
            # Select the first one in the list as default
            combobox::select $warnLBX 0
        } else {
            #set it to editable first
            $warnLBX configure -editable 1
            #Delete current selection
            $warnLBX delete 0 end
            #Add stored selection
            $warnLBX insert 0 "$FlagTags($flags)"
            #Disable edit again
            $warnLBX configure -editable 0
        }
    }

    method SetOptimizationFlags {{flags ""}} {
        global FlagTags
        if {$flags==""} {
            #Let check the build object
            set flags [$b_target GetToolChainFlags $ruleType Optimize]
        } else {
            set flags [$b_target SetToolChainFlags $ruleType Optimize $flags]
        }
        if {$flags==""} {
            # Select the first one in the list as default
            combobox::select $optimizeLBX 0
        } else {
            #set it to editable first
            $optimizeLBX configure -editable 1
            #Delete current selection
            $optimizeLBX delete 0 end
            #Add stored selection
            $optimizeLBX insert 0 "$FlagTags($flags)"
            #Disable edit again
            $optimizeLBX configure -editable 0
        }
    }

    method SetCodeGenerationFlags {{flags ""}} {
        global FlagTags
        if {$flags==""} {
            #Let check the build object
            set flags [$b_target GetToolChainFlags $ruleType CodeGen]
        } else {
            set flags [$b_target SetToolChainFlags $ruleType CodeGen $flags]
        }

        if {$flags==""} {
            # Select the first one in the list as default
            combobox::select $codeLBX 0
        } else {
            #set it to editable first
            $codeLBX configure -editable 1
            #Delete current selection
            $codeLBX delete 0 end
            #Add stored selection
            $codeLBX insert 0 "$FlagTags($flags)"
            #Disable edit again
            $codeLBX configure -editable 0
        }
    }

    method SetUserFlags {{flags ""}} {
	if {$flags==""} {
	    set flags [$b_target GetToolChainFlags $ruleType UserFlags]
	    # Clean current entry
	    $uflagsENT delete 0 end
	    $uflagsENT insert 0 $flags
	} else {
	    $b_target SetToolChainFlags $ruleType UserFlags $flags
	}
    }

    method SetCompilerLocation {{local ""}} {

	set tc_local [$toolchain GetTool $ruleType]
        set bt_local [$b_target GetToolChainFlags $ruleType ToolLocation]

	if {$local==""} {
	    set local $bt_local
	    if {$local==""} {
		set local $tc_local
	    }
	    $exeLEB.txt delete 0 end
	    $exeLEB.txt insert 0 $local
	} else {
	    # Don't save compiler location if
	    # it's the same as the toolchain one.
	    # This may course confusion later.
            if {$local==$tc_local} {
                # Clear the ToolLocation field.
		$b_target SetToolChainFlags $ruleType ToolLocation ""
            } else {
                $b_target SetToolChainFlags $ruleType ToolLocation $local
            }
	}
    }

    method IncludesPage {leaf} {

        set leaffr [frame $leaf.frame]

        # Auto generated includes
        set AutoGenLabel [label $leaffr.aglbl \
				     -text [get_indep String IDEBRAutoGenPathsLabel]]
        set AutoGenList [listbox $leaffr.aglbx -height 3]

        # User includes
        set UserGenLabel [label $leaffr.uglbl \
				     -text [get_indep String IDEBRUserGenPathsLabel]]
        set UserGenList [listbox $leaffr.uglbx -height 3]

        #The Buttons
        set GenButt [button $leaf.gbut -width 11\
                        -text [get_indep String IDEBRGeneratePaths] -under [get_indep Pos IDEBRGeneratePaths] -command "$this generate_cb"]
        set DelButt [button $leaf.dbut -width 11 -text [get_indep String IDEBRDeletePath] -under [get_indep Pos IDEBRDeletePath] -command "$this cb_deletepath"]
        set AddButt [button $leaf.abut -width 11 -text [get_indep String IDEBRAddPath] -under [get_indep Pos IDEBRAddPath] -command "$this cb_addincpath"]

        grid rowconfigure $leaffr 1 -minsize 10
        grid columnconfigure $leaffr 0 -minsize 10

        grid $AutoGenLabel -row 2 -column 1 -columnspan 3 -sticky w
        grid $AutoGenList -row 3 -column 1 -columnspan 3 -sticky we

        grid rowconfigure $leaffr 4 -minsize 10

        grid $UserGenLabel -row 5 -column 1 -columnspan 3 -sticky w
        grid $UserGenList -row 6 -column 1 -columnspan 3 -sticky we

        grid rowconfigure $leaffr 7 -minsize 10
        grid columnconfigure $leaffr 1 -weight 1
        grid columnconfigure $leaffr 2 -weight 1
        grid columnconfigure $leaffr 3 -weight 1

        grid $GenButt -row 1 -column 2
        grid $DelButt -row 2 -column 2
        grid $AddButt -row 3 -column 2

        grid rowconfigure $leaffr 8 -weight 10
        grid columnconfigure $leaffr 9 -minsize 10
        grid rowconfigure $leaffr 9 -minsize 10

        grid $leaffr -column 1 -row 1 -rowspan 3 -sticky we
        grid columnconfigure $leaf 1 -weight 10
        grid columnconfigure $leaf 3 -minsize 10
    }

    method generate_cb {} {

        set includeslist [GenerateIncludesList]
        SetGeneratedIncludes $includeslist

        $b_target SetAutoIncludes $ruleType $includeslist         
    }

    method cb_deletepath {} {
    
        # Get the auto gen list selection
        set selected [$AutoGenList curselect]
	if {$selected==""} {
	    # Nothing selected, check the User list
	    set selected [$UserGenList curselect]
	    if {$selected==""} {
	        # Nothing selected
                return
            }
	    $UserGenList delete $selected
	} else {
	    $AutoGenList delete $selected
	}
    }

    method GenerateIncludesList {} {

        set srcfiles [$b_target GetSourceFiles]

        set includepaths [GenerateIncludePaths $srcfiles]

        return $includepaths
    }

    method SetGeneratedIncludes {{includes ""}} {

        if {$includes==""} {
	   set includes [$b_target GetAutoIncludes $ruleType]
        } else {
            $b_target SetAutoIncludes $ruleType $includes
        }
        	           
        # Clear old entries.
        $AutoGenList delete 0 end

        # Set new entries.
        set tmpcmd "$AutoGenList insert end $includes"
        eval $tmpcmd

        
    }

    method SetUserIncludes {{includes ""}} {
        if {$includes==""} {
	   set includes [$b_target GetUserIncludes $ruleType]
        } else {
	    if {$includes=="<%none%>"} {
		set includes ""
	    }
            $b_target SetUserIncludes $ruleType $includes
        }

	if {$includes!=""} {
        	           
	    # Clear old entries.
	    $UserGenList delete 0 end

	    # Set new entries.
	    set tmpcmd "$UserGenList insert end $includes"
	    eval $tmpcmd
	}
    }

    method DefinesPage {leaf} {

        # User macro definitions
        set UserMacroLabel [label $leaf.deflbl \
				     -text [get_indep String IDEBRMacroDefinesLabel]]
        set UserDefsList [listbox $leaf.deflbx -height 6]
        bind $UserDefsList <ButtonRelease-1> "$this cb_defselect"

        #The Buttons
        set DefDelButt [button $leaf.dbut  -text [get_indep String IDEBRDeleteMacro] -under [get_indep Pos IDEBRDeleteMacro] -width 11 -command "$this cb_deldef"]
        set DefNewButt [button $leaf.nubut -text [get_indep String IDEBRCreateMacro] -under [get_indep Pos IDEBRCreateMacro] -width 11 -command "$this cb_newdef"]
        set DefSetButt [button $leaf.abut -text [get_indep String IDEBRChangeMacro] -under [get_indep Pos IDEBRChangeMacro] -width 11 -command "$this cb_setdef"]

        #The macro entry widget
        set EditDef [entry $leaf.editdef]
        bind $EditDef <KeyRelease> "$this EditDefBoxChanged"


        grid rowconfigure $leaf 1 -minsize 10
        grid columnconfigure $leaf 0 -minsize 10

        grid $UserMacroLabel -row 2 -column 1 -sticky w
        grid $UserDefsList -row 3 -column 1 -rowspan 3 -sticky we

        grid rowconfigure $leaf 6 -minsize 10

        grid $EditDef -row 7 -column 1 -sticky we

        grid $DefNewButt -column 3 -row 3
        grid $DefDelButt -column 3 -row 4
        grid $DefSetButt -column 3 -row 5
        grid columnconfigure $leaf 2 -minsize 10


        grid rowconfigure $leaf 8 -weight 10
        grid columnconfigure $leaf 9 -minsize 10
        grid columnconfigure $leaf 1 -weight 10
        grid rowconfigure $leaf 3 -weight 10
        grid rowconfigure $leaf 4 -weight 10
        grid rowconfigure $leaf 5 -weight 10
        grid rowconfigure $leaf 9 -minsize 10

        DefHandleState
    }

    method SetDefinesList {{defines ""}} {

        if {$defines==""} {
            # Lets checks the build object
            set defines [$b_target GetUserDefines $ruleType]
        } else {
	    if {$defines=="<%none%>"} {
		set defines ""
	    }
            # Set define in build object
            $b_target SetUserDefines $ruleType $defines
        }

        if {$defines!=""} {
            # Populate defines listbox with defines.
            foreach define $defines {
                $UserDefsList insert end $define
            }
        }
    }

    method EditDefBoxChanged {} {
        set entry_value [$EditDef get]

        # Check to see if new Entry box value
        # matches any list box values.
        # Why? so it can be selected from the list
        set matched 0

        set itemnum -1

        foreach item [$UserDefsList get 0 end] {
            incr itemnum
            if {$item==$entry_value} {
                set matched 1
                break;
            }
        }

        if {$matched} {
            $UserDefsList selection clear 0 end
            $UserDefsList selection set $itemnum
        }
            DefHandleState
    }

    method DefHandleState {{selected ""} {entered ""}} {

        # Get Listbox selection
        set selection [$UserDefsList curselect]
        if {$selected == "" && $selection != ""} {
            set selected [$UserDefsList get $selection]
        }

        # Get Text Widget contents.
        if {$entered==""} {
            set entered [$EditDef get]
        }

        #Nothing selected. nothing entered
        if {$selected=="" && $entered==""} {
            $DefNewButt configure -state disabled -default normal
            $DefDelButt configure -state disabled -default normal
            $DefSetButt configure -state disabled -default normal
	    bind $dlgwin <Return> "$okbutt invoke"
            return
        }

        #Nothing selected. something entered
        if {$selected=="" && $entered!=""} {
            $DefNewButt configure -state normal -default active
	    bind $dlgwin <Return> "$DefNewButt invoke"
            $DefDelButt configure -state disabled -default normal
            $DefSetButt configure -state disabled -default normal
            return
        }

        #something selected. something entered (matching)
        if {$selected!="" && $entered==$selected} {
            $DefNewButt configure -state disabled -default normal
            $DefDelButt configure -state normal -default active
	    bind $dlgwin <Return> "$DefDelButt invoke"
            $DefSetButt configure -state disabled -default normal
            return
        }

        #Something selected. Something entered (not matching)
        if {$selected!="" && $entered!="" && $selected!=$entered} {
            $DefNewButt configure -state normal -default active
	    bind $dlgwin <Return> "$DefNewButt invoke"
            $DefDelButt configure -state disabled -default normal
            $DefSetButt configure -state normal -default normal
            return
        }

    }

    method cb_newdef {} {

        # Get the new macro from the edit box.
        set new_def [$EditDef get]

        # Add it to the macros list.
        $UserDefsList insert end "$new_def"
        $UserDefsList selection clear 0 end
        $UserDefsList selection set end
	
	# Clean the edit box.
	$EditDef delete 0 end
	
	# Update the state of the buttons.
        EditDefBoxChanged
    }

    method cb_setdef {} {
        set new_def [$EditDef get]

        set selected [$UserDefsList curselect]
        $UserDefsList delete $selected
        $UserDefsList insert $selected $new_def
        EditDefBoxChanged
    }

    method cb_deldef {} {
        set selected [$UserDefsList curselect]

	if {$selected != ""} {
	    $UserDefsList delete $selected

	    $EditDef delete 0 end
	}
	DefHandleState
    }

    method cb_defselect {} {
        set selection [$UserDefsList curselect]

        if {$selection != ""} {
            set selected [$UserDefsList get $selection]
            $EditDef delete 0 end
            $EditDef insert 0 $selected
        }
        DefHandleState
    }
    
    method cb_addincpath {} {
        set include_path [Editor& @@ DirDialog $dlgwin -title "Add Include Path:"]
	
	# Check that a path was selected
	if {$include_path!=""} {
	    #TODO: check it's unique
    
            $UserGenList insert end $include_path
	}
    }

    method ok_cb {} {
        SaveData
        global tkPriv
        set tkPriv($dlgwin,button) 1
    }

    method SaveData {} {

        # debug settings
        SetDebugFlags $debugLookUp([$debugLBX get])

        # optimization settings
        SetOptimizationFlags $optimizeLookUp([$optimizeLBX get])

        # code generation settings
        SetCodeGenerationFlags $codeLookUp([$codeLBX get])

        # Warning level settings
        SetWarningFlags $warnLookUp([$warnLBX get])

	# User defined compiler flags
        $b_target SetToolChainFlags $ruleType UserFlags [$uflagsENT get]

	# Compiler tool.
	SetCompilerLocation [$exeLEB.txt get]

	# Save Auto Includes
	SetGeneratedIncludes [$AutoGenList get 0 end]

	# Save User Includes
	#(Pass it a secret message in they are no includes)
	set includes [$UserGenList get 0 end]
	if {$includes==""} {
	    set includes "<%none%>"
	}
	SetUserIncludes $includes

        # Save Defines
	#(Pass it a secret message in they are no defines)
	set defines [$UserDefsList get 0 end]
	if {$defines==""} {
	    set defines "<%none%>"
	}
        SetDefinesList $defines
    }


    method cancel_cb {} {
        global tkPriv
        set tkPriv($dlgwin,button) 1
    }

    method DestroyDialog {} {
        # Delete all the objects.
        destroy $dlgwin
        $exeLEB delete
    }
}

proc GenerateIncludePaths {srcfiles} {

    # Check paf_db_iu exists
    if {[info command paf_db_iu]==""} {
    	# The Includes database hasn't been created.
	return ""
    }

    set all_includefiles ""
    set all_includepaths ""

    # Get the included files for each source file
    foreach srcfile $srcfiles {
        set includefiles [paf_db_iu seq -col 0 -end $srcfile]
        set all_includefiles [concat $all_includefiles $srcfile]
    }

    # Strip them down to the paths
    foreach includefile $all_includefiles {
        set includepath [file dirname $includefile]
        set all_includepaths [concat $all_includepaths $includepath]
    }

    # Remove and duplicates
    set all_includepaths [lsort $all_includepaths]
    set all_includepaths [lunique $all_includepaths]

    return $all_includepaths
}

proc TestIt {tc} {
    snIdeToolsDlg tst
    tst configure -toolchain $tc -ruleSuffix CC
    tst CreateDialog
}


