# 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.
# 
################################################
##
## Target Editor Dialog for SN-IDE.
## Copyright (c) 1999 Cygnus Solutions, Inc.
## Written by Ian Roxborough <irox@cygnus.com>
##
################################################

#This hack will be removed when the build
#automatically takes care of the libgui tcl files

if {![info exists combobox::combobox]} {
    source $sn_home/share/cygnus/gui/combobox.tcl
}

# Making up Itcl1.5
# This global is only used to togle the radio buttons
# (debug and launch) in the linker tab.
# (I hate doing crap like this)
set rb_global_debug_state "0" ; # Will be debug by default.

itcl_class snEditTarget {
#    inherit itk::Toplevel

    # public methods
    #public method constructor {target_name {args ""}}
    #public method CreateDialog {}

    # private methods
    #private method InitalizeData {}
    #private method AddSrcPage {notebook}
    #private method AddLibPage {notebook}
    #private method AddRulesPage {notebook}
    #private method AddLinkPage {notebook}

    # public variables
    public TargetName "" ; # Target Name as store in db.
    public NewTarget ""  ; # Set to one if it's a new target.

    # protected variables
    protected thisTail

    # Main dialog.
    protected bDirLEB       ; # build dir entry widget
    protected tTypeCBX      ; # target type combobox
    protected tChainCBX     ; # target toolchain combobox

    # Source files tab.
    protected srctree       ; # Source file tree (target files)
    protected srctree2      ; # Source file tree (project files)
    protected src_file_list "" ; # list of source files

    # Libraries tab.
    protected libLBX ""     ; # List of libraries to link in.
    protected libadd ""	    ; # the add library button.
    protected libdel ""	    ; # delete library button.
    protected libup ""	    ; # move lib up one in link order.
    protected libdown ""    ; # move lib down one in link order.

    # Build rules tab.
    protected ruletable     ; # table of rules.
    protected rulesindex    ; # Array of rules indexed by pos in table.
    protected displaycmdline ; # widget for cmd line args.
    protected ruledisen      ; # Rule disable/enable togle button.
    protected ruleedit       ; # Rule edit button.

    # Link rules tab.
    protected linkFilenameEntry ; # binary output file name.
    protected linkUserFlagsEntry ; # user linking flags.
    protected entryPointEntry ; # The application entry point.
    protected linkExecLEB ; # The linker executable.
    protected linkcmdline ; # Used to display full linker args.
    protected debugRadio ; # Radiobutton for selecting launch debugger.
    protected launchRadio ; # Radiobutton for launch without debugger.
    protected execCmdEntry ; # Command Line to launch or debug build.

    
    public b_target     ; # Build target object


    method constructor {target_name {config ""}} {
        global tkPriv
        #TODO: check target_name is valid

        set tail "tail"
        set thisTail "$this$tail"
        #set thisTail [namespace tail $this]

        set TargetName $target_name

#        if {$args!=""} {$thisTail configure $args}

        CreateDialog
	
	set focus [focus]
	if {$focus == ""} {
            set focus "."
	} else {
            set focus [winfo toplevel $focus]
	}
	if {[wm state $focus] == "normal"} {
	    wm transient $thisTail $focus
	}
	
        InitalizeData
	# Make the dialog modal	
        grab_focus
	bind_focus_enter $thisTail {catch {focus %W}}

	#catch {$dlgwin resizable yes no}
        grab_focus
	focus $thisTail
	tkwait variable tkPriv($thisTail,button)
        $this delete


    }

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

    ##################################################
    # snEditTarget::InitalizeData
    #
    # This create a build target object and load the
    # target data from the db to the object which is
    # used to supply the settings for the dialog.
    #
    method InitalizeData {} {

        set b_target [snBuildTarget .te_target_data]

        $b_target LoadData $TargetName

        SetTargetType
        SetToolChain
        SetBuildDirectory
	SetLibraryFiles

        SetSourceFiles
	
        # Linker rule	
	SetOutputFilename
	SetLinkerEntryPoint
	SetUserLinkFlags
	SetLinkerExecutable
	SetLaunchDebugerInfo
	SetLaunchCommandLine

	#SetLibraryFiles
	HandleLibsTabState

        SetBuildRules
	UpdateCmdLine
    }


    ##################################################
    # snEditTarget::CreateDialog
    #
    # This deals with the drawing and layout of the
    # Edit Target dialog box.
    #

    method CreateDialog {} {

        toplevel $thisTail

        wm title $thisTail "[get_indep String IDETargetEdTitle] $TargetName"

	# Settings frame
	set sframe [frame $thisTail.fr]

        # Create notebook widget
        set notebook [tixNoteBook $sframe.nb]
        $notebook conf -width 500 -height 400

        # Add the leafs
        AddSrcPage $notebook
        AddLibPage $notebook
        AddRulesPage $notebook
        AddLinkPage $notebook

        # Add Build Directory Widget
        set get_dir_cmd "sn_choose_dir $sframe.bdirleb.txt"
        set bDirLBL [label $sframe.bdirlbl -text [get_indep String IDETEBuildDir] \
	                               -under [get_indep Pos IDETEBuildDir]]
        set bDirLEB [LabelEntryButton& $sframe.bdirleb \
                                       -text "" -command $get_dir_cmd]

        # Add Target Type combobox
        set tTypeLBL [label $sframe.ttypelbl -text [get_indep String IDETETargetType] \
	                               -under [get_indep Pos IDETETargetType]]
        set tTypeCBX [combobox::combobox $sframe.ttypecbx -command "$this grab_focus"]

        # N.B.: We should check the tool chain to see what types
        # of builds are supported, but for now lets just
        # assume it's Executable, Library, DLL (Shared Library).

        $tTypeCBX listinsert end "Executable"
        $tTypeCBX listinsert end "Library"
        $tTypeCBX configure -editable 0
        # Add Tool Chain combobox
        set tChainLBL [label $sframe.tchainlbl -text [get_indep String IDETEToolChain] \
	                               -under [get_indep Pos IDETEToolChain] ]
        set tChainCBX [combobox::combobox $sframe.tchaincbx -command "$this ToolChainChanged $this"]

        # TODO: Get list of tool chains.
        set ToolChainList "{GNUPro (native)}"
        set tmpcmd "$tChainCBX listinsert 0 $ToolChainList"
        eval $tmpcmd
	$tChainCBX listinsert end {GNUPro (PowerPC linux)}
	$tChainCBX listinsert end {GNUPro (Embedded x86 linux)}
	
        # Add OK/Cancel Buttons
        set ok_but [button $thisTail.ok -text [get_indep String IDETEOK] -command "$this ok_cb" -width 11]
        set cancel_but [button $thisTail.canit -text [get_indep String IDETECancel] -command "$this cancel_cb" -width 11]

	# Bind Escape and close window button to Cancel
	wm protocol $thisTail WM_DELETE_WINDOW "$cancel_but invoke"
	bind $thisTail <Escape> "$cancel_but invoke"

	# Binf Return to the OK button.
        bind $thisTail <Return> "$ok_but invoke"


        ::grid columnconfigure $sframe 0 -minsize 10
        ::grid rowconfigure $sframe 1 -minsize 10

        ::grid $notebook -column 1 -row 2 -rowspan 14 -sticky news

        ::grid columnconfigure $sframe 2 -minsize 8
        ::grid rowconfigure $sframe 2 -minsize 15

        ::grid $bDirLBL -column 3 -row 3 -sticky w
        ::grid $bDirLEB -column 3 -row 4 -sticky we

        ::grid rowconfigure $sframe 5 -minsize 8

        ::grid $tTypeLBL -column 3 -row 6 -sticky w
        ::grid $tTypeCBX -column 3 -row 7 -sticky we

        ::grid rowconfigure $sframe 8 -minsize 8

        ::grid $tChainLBL -column 3 -row 9 -stick w
        ::grid $tChainCBX -column 3 -row 10 -stick we

	::grid rowconfigure $sframe 11 -minsize 8
        ::grid rowconfigure $sframe 15 -weight 8
	
#	::grid $pTypeLBL -column 3 -row 12 -sticky w
#	::grid $pTypeDetectCKB -column 3 -row 14 -sticky w
#	::grid $pTypelistCBX -column 3 -row 13 -sticky we

        ::grid columnconfigure $sframe 4 -minsize 8
        ::grid rowconfigure $sframe 16 -minsize 8

        pack $sframe -fill both
	pack $cancel_but $ok_but -pady 3 -padx 3 -side right
	
    }
    
    method ToolChainChanged {{my_this} {dummy1 ""} {tool_chain ""}} {

	# Set the new toolchain.
	$b_target SetToolChain $tool_chain
	
	# Set the linker to reflect the new toolchain.
	SetLinkerExecutable
	
	# Update the command lines in build rules and link rules.
	$my_this UpdateCmdLine
	
	# regrab the focus since sometimes the combox
	# will loss focus on our modal dialog box.
	grab_focus
    }

    method AddSrcPage {notebook} {

	global sn_options

        #Add leafs for source files.
        set leaf [$notebook add src -label [get_indep String IDETESourceFilesTab] \
	                               -under [get_indep Pos IDETESourceFilesTab]]
        frame $leaf.trfr1 -relief sunken -borderwidth 2
        set srctree [sn_treetable $leaf.trfr1 -selectmode extended \
			-height 10 -width 1 -indent 20 \
			-font $sn_options(def,default-font) \
			-selectforeground $sn_options(def,select-fg) \
			-selectbackground $sn_options(def,select-bg) \
			-relief sunken -bw 2]
        grid $srctree $leaf.trfr1.y -sticky news
	grid $leaf.trfr1.x -sticky news
	grid columnconfigure $leaf.trfr1 0 -weight 1
	grid rowconfigure $leaf.trfr1 0 -weight 1

        frame $leaf.trfr2 -relief sunken -borderwidth 2
        set srctree2 [sn_treetable $leaf.trfr2 -selectmode extended \
			-height 10 -width 1 -indent 20 \
			-font $sn_options(def,default-font) \
			-selectforeground $sn_options(def,select-fg) \
			-selectbackground $sn_options(def,select-bg) \
			-relief sunken -bw 2]
        grid $srctree2 $leaf.trfr2.y -sticky news
	grid $leaf.trfr2.x -sticky news
	grid columnconfigure $leaf.trfr2 0 -weight 1
	grid rowconfigure $leaf.trfr2 0 -weight 1
 
#        eval $srctree insert 0 -text "<Empty>"
		
        set AllProjectFiles [sn_project_file_list 0]

        $srctree2 delete 0 end
        $srctree2 insert 0 -text Files
        fill_file_tree  -widget $srctree2 \
	        -contents $AllProjectFiles \
	        -parent 0

        button $leaf.arf -text [get_indep String IDETEAddFiles] \
	                               -under [get_indep Pos IDETEAddFiles] \
				       -width 11 -command "$this AddSourceFiles"

        set pfiles [label $leaf.pfs -text [get_indep String IDETEProjectFiles]]
        set tfiles [label $leaf.tfs -text [get_indep String IDETETargetFile]]

        set clearbut [button $leaf.clbut -text [get_indep String IDETEClearFile] \
	                               -under [get_indep Pos IDETEClearFile] \
				       -width 11 -command "$this RemoveSourceFiles"]
        set clearallbut [button $leaf.clallbut -text [get_indep String IDETEClearAllFiles] -width 11 -command "$this RemoveAllSourceFiles"]
        set impfilebut [button $leaf.impfbut -text [get_indep String IDETEImportFiles] -width 11 -command "$this import_files"]
        set impdirbut [button $leaf.impdbut -text [get_indep String IDETEImportDir] -width 11 -command "$this import_dir"]
        set implbl [label $leaf.implbl -text [get_indep String IDETEImportLabel]]

        @@grid columnconfigure $leaf 0 -minsize 10
        @@grid rowconfigure $leaf 11 -minsize 10 
        @@grid rowconfigure $leaf 10 -weight 10 
        @@grid $pfiles -column 1 -row 2 -sticky w
        @@grid $leaf.trfr2 -column 1 -row 3 -rowspan 8 -sticky news

        @@grid columnconfigure $leaf 2 -minsize 10

        @@grid $leaf.arf -column 3 -row 3  -pady 4
        @@grid $clearbut -column 3 -row 4 -pady 4
        @@grid $clearallbut -column 3 -row 5 -pady 4
        @@grid rowconfigure $leaf 6 -minsize 20
        @@grid $implbl -column 3 -row 7 -pady 4
        @@grid $impfilebut -column 3 -row 8 -pady 4
        @@grid $impdirbut -column 3 -row 9 -pady 4

        @@grid columnconfigure $leaf 4 -minsize 10
        
        @@grid $tfiles -column 5 -row 2 -sticky w
        @@grid $leaf.trfr1 -column 5 -row 3 -rowspan 8 -sticky news

	@@grid columnconfigure $leaf 5 -weight 10
	@@grid columnconfigure $leaf 1 -weight 10
        @@grid columnconfigure $leaf 6 -minsize 10

    }

    method AddSourceFiles {} {
        set sels [$srctree2 curselection]
        set newfiles [build_file_list $srctree2 tree $sels]

        $b_target AddSourceFiles $newfiles
#        foreach newfile $newfiles {
#            lappend src_file_list $newfile
#        }

        #delete old entries
        $srctree delete 0 end
        $srctree insert 0 -text Files
        fill_file_tree  -widget $srctree \
	        -contents [$b_target GetSourceFiles] \
       	        -parent end

	# Make sure the command lines are upto date.	
        UpdateCmdLine
    }

    method RemoveSourceFiles {} {
        set sels [$srctree curselection]
        set deadfiles [build_file_list $srctree tree $sels]

        $b_target RemoveSourceFiles $deadfiles

        #delete old entries
        $srctree delete 0 end
        $srctree insert 0 -text Files
        fill_file_tree  -widget $srctree \
	        -contents [$b_target GetSourceFiles] \
	        -parent end

	# Make sure the command lines are upto date.	
        UpdateCmdLine
    }

    method RemoveAllSourceFiles {} {
    
        $b_target SetSourceFiles ""

        #delete old entries
        $srctree delete 0 end
        $srctree insert 0 -text Files
        fill_file_tree  -widget $srctree \
	        -contents [$b_target GetSourceFiles] \
	        -parent end
		
	# Make sure the command lines are upto date.	
        UpdateCmdLine
    }

    method AddLibPage {notebook} {
        #Add leafs for libraries files.
        set leaf [$notebook add lib -label [get_indep String IDETELibraryFileTab] \
	                               -under [get_indep Pos IDETELibraryFileTab]]

        set libLBL [label $leaf.liblbl -text [get_indep String IDETELibraryLabel]]

	set libLBXframe [frame $leaf.liblbxfr -relief sunken -borderwidth 2]
        set libLBX [listbox $libLBXframe.liblbx -relief flat \
			-yscrollcommand [list $libLBXframe.scrolly set]]
	set libLBX_scroll_y [scrollbar $libLBXframe.scrolly -orient vertical \
				 -command [list $libLBX yview]]
        grid $libLBX $libLBX_scroll_y -sticky news
	grid rowconfigure $libLBXframe 0 -weight 1
	grid columnconfigure $libLBXframe 0 -weight 1

        set libadd [button $leaf.add -text [get_indep String IDETEAddLib] \
	                               -under [get_indep Pos IDETEAddLib] \
				       -width 11 -command "$this cb_add_lib"]
        set libdel [button $leaf.del -text [get_indep String IDETERemoveLib] \
	                               -under [get_indep Pos IDETERemoveLib] \
				        -width 11 -command "$this cb_del_lib"]
        set libup [button $leaf.up -text [get_indep String IDETEMoveUp] \
	                               -under [get_indep Pos IDETEMoveUp] \
				       -width 11 -command "$this cb_up_lib"]
        set libdown [button $leaf.down -text [get_indep String IDETEMoveDown] \
	                               -under [get_indep Pos IDETEMoveDown] \
				        -width 11 -command "$this cb_down_lib"]

        grid $libLBL -column 1 -row 2 -sticky w
        grid $libLBXframe -column 1 -row 3 -rowspan 5 -sticky news
        bind $libLBX <ButtonRelease> "$this cb_double_click_lib" 

        grid $libadd -column 4 -row 3 -pady 3
        grid $libdel -column 4 -row 4 -pady 3
        grid $libup -column 4 -row 5 -pady 3
        grid $libdown -column 4 -row 6  -pady 3

        grid rowconfigure $leaf 7 -weight 10
        grid columnconfigure $leaf 1 -weight 10

        grid rowconfigure $leaf 1 -minsize 10
        grid rowconfigure $leaf 8 -minsize 10
        grid columnconfigure $leaf 0 -minsize 10
        grid columnconfigure $leaf 3 -minsize 10
        grid columnconfigure $leaf 5 -minsize 10

    }

    method import_dir {} {

        set dir [Editor& @@ DirDialog $thisTail \
                     -title "Import Directory"]
        set importedSrcFiles [sn_glob $dir]

	if {$importedSrcFiles!=""} {
            $b_target AddSourceFiles $importedSrcFiles

            #delete old entries
            $srctree delete 0 end
            $srctree insert 0 -text Files
            fill_file_tree  -widget $srctree \
	            -contents [$b_target GetSourceFiles] \
       	            -parent end

            # Make sure the command lines are upto date.	
            UpdateCmdLine
        }
    }

    method import_files {} {
    
        set importedSrcFiles [Editor& @@ FileDialog $thisTail -multiple 1]
	
	if {$importedSrcFiles!=""} {
            $b_target AddSourceFiles $importedSrcFiles

            #delete old entries
            $srctree delete 0 end
            $srctree insert 0 -text Files
            fill_file_tree  -widget $srctree \
	            -contents [$b_target GetSourceFiles] \
       	            -parent end

            # Make sure the command lines are upto date.	
            UpdateCmdLine
        }
    }

    method AddRulesPage {notebook} {
        #Add leafs for build rules.
        set leaf [$notebook add rule -label [get_indep String IDETEBuildRulesTab] \
	                               -under [get_indep Pos IDETEBuildRulesTab] ]
        set ruletablefr [frame $leaf.rule_frame]
        set ruletable [Tree& $ruletablefr.rlztable -tabs {70 100 420} \
                              -filter "" -indentwidth 20 \
                              -tabsize 2 \
                              -labels "{Status} {File Type} {Description}" ]
        pack $ruletable -fill both
#        $ruletable config -width 10 -height 9

        $ruletable bind <Double-1> "$this ruletable_double_cb"
        $ruletable bind <ButtonRelease-1> "$this UpdateCmdLine"
        $ruletable bind <KeyRelease> "$this UpdateCmdLine"
        $ruletable bind <Expose> "$this rules_tab_selected_hack"
        set ruledisen [button $leaf.togenable -text [get_indep String IDETEBuildRuleDisable] \
	                               -under [get_indep Pos IDETEBuildRuleDisable] \
				       -width 11 -command "$this cb_rule_togle"]
        set ruledel [button $leaf.del -text "Delete" -width 11]
        set ruledup [button $leaf.dup -text "Duplicate" -width 11]
        set rulenew [button $leaf.new -text "New Rule" -width 11]
        set ruleedit [button $leaf.edit -text [get_indep String IDETEBuildRuleEdit] \
	                               -under [get_indep Pos IDETEBuildRuleEdit] -width 11 \
				       -command "$this ruletable_double_cb"]
        set displaycmdline [text $leaf.cmdline -width 1]

        ::grid rowconfigure $leaf 1 -minsize 10
        ::grid columnconfigure $leaf 0 -minsize 10
        ::grid $ruletablefr -column 1 -columnspan 5 -row 2 -rowspan 2 -stick we

        ::grid rowconfigure $leaf 4 -minsize 10


# The following commented out item will not appear in 99r1
#        ::grid $ruledel -column 2 -row 5
#        ::grid $ruledup -column 3 -row 5
#        ::grid $rulenew -column 4 -row 5

        ::grid $ruleedit -column 2 -row 5
        ::grid $ruledisen -column 4 -row 5

        ::grid columnconfigure $leaf 1 -weight 10
        ::grid columnconfigure $leaf 2 -weight 1
        ::grid columnconfigure $leaf 3 -weight 10
        ::grid columnconfigure $leaf 4 -weight 1
        ::grid columnconfigure $leaf 5 -weight 10

        ::grid columnconfigure $leaf 6 -minsize 10
        ::grid rowconfigure $leaf 6 -minsize 10

        ::grid $displaycmdline -column 1 -columnspan 5 -row 7 -sticky news

        ::grid rowconfigure $leaf 7 -weight 10
        ::grid rowconfigure $leaf 8 -minsize 10
  #      rules_tab_selected_hack
    }

    method AddLinkPage {notebook} {
        #Add leafs for linking rules.
        set leaf [$notebook add link -label [get_indep String IDETELinkRulesTab] \
	                               -under [get_indep Pos IDETELinkRulesTab]]

        # Binary output files name.
        set linkFilenameLabel [label $leaf.lfilelbl -text [get_indep String IDETELinkOutputFile]]
        set linkFilenameEntry [entry $leaf.lfileent]

        # User specified link flags.
        set linkUserFlagsLabel [label $leaf.lflagslbl -text [get_indep String IDETELinkFlags]]
        set linkUserFlagsEntry [entry $leaf.lflagsent]

        # Linker executable.
        set linkExecLabel [label $leaf.execlbl -text [get_indep String IDETELinkerExe] \
	                               -under [get_indep Pos IDETELinkerExe]]
	set linkExecLEB [LabelEntryButton& $leaf.execleb -text ""]

        #Todo: get link debug information from the toolchain

        #Combobox for Debug linking info
        set linkDebugLabel [label $leaf.dbglbl -text "Debug:"]
        set linkDebugCombo [combobox::combobox $leaf.dbgcbx]

        #Todo: get optimization information from the toolchain

        #Combobox for Optimize linking info
        set linkOptimiLabel [label $leaf.optlbl -text "Optimization:"]
        set linkOptimiCombo [combobox::combobox $leaf.optcbx]

        #Todo: get link warning information from the toolchain

        #Combobox for Warnings at link time
        set linkWarnLabel [label $leaf.wrnlbl -text "Warnings:"]
        set linkWarnCombo [combobox::combobox $leaf.wrmcbx]

        #Entry box for entrypoint 
        set entryPointLabel [label $leaf.enptlbl -text "Entry Point:"]
        set entryPointEntry [entry $leaf.enptent]
        set linkcmdline [text $leaf.cmdline -width 1]

        # Launch settings.
        set launchLabel [label $leaf.lunchlabel -text [get_indep String IDETELaunchSettingsLabel]]

        #Entry box for exec command
        set execCmdLabel [label $leaf.execmdent -text [get_indep String IDETELaunchCommand]]
        set execCmdEntry [entry $leaf.execcmdent]

        # Launch/debug radio buttons.
	set radioFrame [frame $leaf.radfram]
        set debugRadio [radiobutton $radioFrame.dbgrad -text [get_indep String IDETELaunchDebug] \
	                               -under [get_indep Pos IDETELaunchDebug] \
				       -command "$this cb_radio_debug" -value 1 -variable rb_global_debug_state]
        set launchRadio [radiobutton $radioFrame.lnchrad -text  [get_indep String IDETELaunchExecute] \
	                               -under [get_indep Pos IDETELaunchExecute] \
				       -command "$this cb_radio_launch" -value 2 -variable rb_global_debug_state]
        pack $debugRadio $launchRadio -side right -padx 10

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

        grid $linkFilenameLabel -row 2 -column 1 -sticky e
        grid $linkFilenameEntry -row 2 -column 2 -sticky we

        grid rowconfigure $leaf 3 -minsize 10
	
	grid $linkUserFlagsLabel -row 4 -column 4 -sticky e
	grid $linkUserFlagsEntry -row 4 -column 5 -sticky we

	grid $linkExecLabel -row 4 -column 1 -sticky e
	grid $linkExecLEB -row 4 -column 2 -sticky we
# not useful for sn99r1
#        grid $linkDebugLabel -row 4 -column 1 -sticky e
#        grid $linkDebugCombo -row 4 -column 2 -sticky we

#        grid columnconfigure $leaf 3 -minsize 10

#        grid $linkOptimiLabel -row 4 -column 4 -sticky e
#        grid $linkOptimiCombo -row 4 -column 5 -sticky we

#        grid rowconfigure $leaf 5 -minsize 10

#        grid $linkWarnLabel -row 6 -column 1 -sticky e
#        grid $linkWarnCombo -row 6 -column 2 -sticky we

        grid $entryPointLabel -row 2 -column 4 -sticky e
        grid $entryPointEntry -row 2 -column 5 -sticky we
#        grid rowconfigure $leaf 7 -minsize 10

        grid $linkcmdline -row 8 -column 1 -columnspan 5 -sticky news -pady 14

        grid rowconfigure $leaf 8 -weight 15
#        grid rowconfigure $leaf 9 -minsize 10

        grid $launchLabel -row 10 -column 1 -columnspan 5 -sticky w

        grid rowconfigure $leaf 11 -minsize 7

	grid $execCmdLabel -row 12 -column 1 -columnspan 2 -sticky w
	grid $execCmdEntry -row 13 -column 1 -columnspan 5 -sticky we
	grid $radioFrame -row 11 -rowspan 2 -column 3 -columnspan 3 -sticky we

	grid rowconfigure $leaf 14 -minsize 10

	grid columnconfigure $leaf 2 -weight 10
	grid columnconfigure $leaf 5 -weight 10
	grid columnconfigure $leaf 6 -minsize 10

    }

    method SetOutputFilename {{file_name ""}} {
        if {$file_name==""} {
	    # Let's try the build object.
	    set file_name [$b_target GetOutputFilename]
	} else {
	    $b_target SetOutputFilename $file_name
	}
	# Clear current settings.
	$linkFilenameEntry delete 0 end
	$linkFilenameEntry insert 0 $file_name
    }

    method SetUserLinkFlags {{flags ""}} {
        if {$flags==""} {
	    # Let's check the build object.
	    set flags [$b_target GetUserLinkFlags]
	} else {
	    if {$flags=="%none%"} {
	        set flags ""
	    }
	    $b_target SetUserLinkFlags $flags
	}
	
	# clear previous contense.
	$linkUserFlagsEntry delete 0 end
	$linkUserFlagsEntry insert 0 $flags
    }

    method SetLinkerEntryPoint {{entry_point ""}} {
        if {$entry_point==""} {
	    # Let's check the build object.
	    set entry_point [$b_target GetLinkerEntryPoint]
	} else {
	    if {$entry_point=="%none%"} {
	        set entry_point ""
	    }
	    $b_target SetLinkerEntryPoint $entry_point
	}
	
	# clear previous contense.
	$entryPointEntry delete 0 end
	$entryPointEntry insert 0 $entry_point
    }
    
    method SetLinkerExecutable {{linker ""}} {
	
        if {$linker!=""} {
	    # Store linker in build object
	    $b_target SetLinkerLocation $linker
        }
    
        if {$linker==""} {
            # Get linker tool from the build objects ToolLocation.
            set linker [$b_target GetLinkerLocation]
        }

        $linkExecLEB.txt delete 0 end
        $linkExecLEB.txt insert 0 $linker

    }
    
    method UpdateCmdLine {} {

        set tool_chain [$tChainCBX get]
        set tchain_obj [GetToolChainObject $tool_chain]

        set sel [$ruletable curselection]
        if {$sel==""} {
            #Nothing is selected, use 0 as default.
            set sel 0
            }

        set cmdline [GetCompilerCommandLine $tchain_obj $rulesindex($sel)]

        # clear widget
	$displaycmdline configure -state normal
        $displaycmdline delete 0.0 end
        $displaycmdline insert end $cmdline
	$displaycmdline configure -state disabled

        # Get linker 
        SetLinkerExecutable

        # Update the linker command line
	set cmdline [GetLinkerCommandLine $tchain_obj]
	$linkcmdline configure -state normal
        $linkcmdline delete 0.0 end
        $linkcmdline insert end $cmdline
	$linkcmdline configure -state disabled
 	
        HandleRuleTableState
    }

    method GetCompilerCommandLine {tool_chain rule_type} {

        # Get the tool
        set tool [$b_target GetToolChainFlags $rule_type ToolLocation]
        if {$tool==""} {
            set tool [$tool_chain GetTool $rule_type]
        }

        # Get the basic action
        set basicaction [$tool_chain GetBasicAction $rule_type]

        # Get the flags
        set flags ""
	foreach flagstype "Debug Optimize Warning CodeGen" {
	    set flagsetting [$b_target GetToolChainFlags $rule_type $flagstype]
	    set flags "$flags [$tool_chain GetRuleFlags $rule_type $flagstype $flagsetting]"
	}

	# Get user flags
	set userflags [$b_target GetToolChainFlags $rule_type UserFlags]

	# Get the marco defs
	set defines_list [$b_target GetUserDefines $rule_type]
	set defines_spec [$tool_chain FormatDefines $rule_type $defines_list]

	# Get the include paths
	set includes_list1 [$b_target GetUserIncludes $rule_type]
	set includes_list2 [$b_target GetAutoIncludes $rule_type]
	set includes_list [concat $includes_list1 $includes_list2]
	set include_spec [$tool_chain FormatIncludes $rule_type $includes_list]

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

    method GetLinkerCommandLine {tool_chain} {
    	global sn_elix

        set linker [$b_target GetLinkerLocation]
        set linkerflags [$linkUserFlagsEntry get]
        set basicflags [$tool_chain GetExeLinkerRule]

	set entrypoint [$entryPointEntry get]
	if {$entrypoint!=""} {
            set projecttype [$b_target GuessProjectType]
            set entrypflag [$tool_chain GetLinkerEntryPointFlag $projecttype]
            set entrypoint "$entrypflag$entrypoint"
	}
	
        set objfiles [$tool_chain GetObjectFileList [$b_target GetSourceFiles]]
	
	set libfiles [$libLBX get 0 end]

        set outputfile [$linkFilenameEntry get]

	# EL/IX change: for embedded systems, use `elix-link' to do
	# the link.
	if {$sn_elix && [$tool_chain GetIsEmbedded]} {
	    global sn_options

	    set prefix [file join [pwd] [$b_target GetBuildDirectory]]/
	    set mode ""
	    if {[$b_target GetLaunchWithDebugger]} {
		set mode "--mode debug"
	    }

	    set cmdline "elix-link --prefix $prefix --output $outputfile $mode -- $linker $entrypoint $linkerflags $objfiles $libfiles\n"
	} else {
	    set cmdline "$linker $basicflags $outputfile $entrypoint $linkerflags $objfiles $libfiles\n"
	}

        return $cmdline
 
    }
    
    # Call back if the radio button mark debug in the linker rules
    # selected.
    method cb_radio_debug {} {

        # Select debug.
        $debugRadio select
	
	# unselect launch
	$launchRadio deselect
	
        # Set to use debugger.
        $b_target SetLaunchWithDebugger 1
    }
    
    # Call back if the radio button mark debug in the linker rules
    # selected.
    method cb_radio_launch {} {

        # unselect debug.
        $debugRadio deselect
	
	# select launch
	$launchRadio select

        # set not to use debugger.
        $b_target SetLaunchWithDebugger 0
    }
    
    method SetLaunchCommandLine {} {
        $execCmdEntry delete 0 end 
        $execCmdEntry insert 0 [$b_target GetLaunchCommandLine]
    }
    
    method SetLaunchDebugerInfo {{use_debugger ""}} {
        if {$use_debugger==""} {
	    # Get it from the build target.
	    set use_debugger [$b_target GetLaunchWithDebugger]
	} else {
	    # Set it in the build target.
	    $b_target SetLaunchWithDebugger $use_debugger
	}
	
	if {$use_debugger==1} {
	    $launchRadio deselect
	    $debugRadio select
	} else {
	    $launchRadio select
	    $debugRadio deselect
	}
        
    }

    method SetLibraryFiles {{lib_files ""}} {
        if {$lib_files==""} {
	    set lib_files [$b_target GetLibraryFiles]
	} else {
	    if {$lib_files=="none"} {
	        set lib_files ""
	    }
	    $b_target SetLibraryFiles $lib_files
	}
	
	$libLBX delete 0 end
	set tmpcmd "$libLBX insert end $lib_files"
	eval $tmpcmd
    }

    method SetBuildDirectory {{dir ""}} {

	global sn_options

        if {$dir==""} {
            # Lets see if we can get for build target object
            set dir [$b_target GetBuildDirectory]
        } else {
            # Lets write this data
            $b_target SetBuildDirectory $dir
        }

        if {$dir==""} {
            # Set the build dir to the project dir.
            set dir $sn_options(sys,project-dir)
            $b_target SetBuildDirectory $dir
        }

        $bDirLEB.txt delete 0 end
        $bDirLEB.txt insert end $dir

    }

    method SetTargetType {{type ""}} {

        if {$type==""} {
            # Lets see if we can get for build target object
            set type [$b_target GetTargetType]
        } else {
            # Lets write this data
            $b_target SetTargetType $type
        }

        if {$type==""} {
            # Use Executable as default 
            set type "Executable"
        }
	$tTypeCBX configure -editable 1
        $tTypeCBX delete 0 end
        $tTypeCBX insert 0 $type
	$tTypeCBX configure -editable 0
    }

    method SetToolChain {{tools ""}} {

        if {$tools==""} {
            # Lets see if we can get for build target object
            set tools [$b_target GetToolChain]
            if {$tools!=""} {
                # Write it back initialise the tool chain field.
                # (Can cause side effects if we don't.)
                $b_target SetToolChain $tools
            }
        } else {
            # Lets write this data
            $b_target SetToolChain $tools
        }

        if {$tools==""} {
            # Use Executable as default 
            set tools "GNUPro (native)"
            $b_target SetToolChain $tools
        }
        $tChainCBX configure -editable 1
        $tChainCBX delete 0 end
        $tChainCBX insert 0 $tools
        $tChainCBX configure -editable 0
    }

    method SetSourceFiles {{files ""}} {
         if {$files==""} {
            # Lets see if we can get for build target object
            set files [$b_target GetSourceFiles]
        } else {
            # Lets write this data
            $b_target SetSourceFiles $tools
        }

        if {$files!=""} {
        $srctree delete 0 end
        $srctree insert 0 -text Files
        fill_file_tree  -widget $srctree \
                        -contents $files \
                        -parent end
        }
    }

    method SetBuildRules {{cls ""} {dummy ""}} {
        #set tool_chain [$tChainCBX get]
	# Since this is being call be Tree& before

        # Get toolchain and select the right spex.
        DummyCreateToolChain_spec
        #set tchain_obj [GetToolChainObject $tool_chain]
        set tchain_obj GNUPro
	
        set rules [$tchain_obj GetRulesList]
        set rulenum -1
	
        # Clean rule table
        $ruletable.tree delete 0 end

        #Write rules...
        foreach rule $rules {
            incr rulenum
            set rulesindex($rulenum) $rule
            set finfo [$tchain_obj GetFileInfo $rule]
            set ginfo [$tchain_obj GetGeneralInfo $rule]
            set rule_status [$b_target GetRuleStatus $rule]
            set info "\{$rule_status\t$finfo\t$ginfo\}"
            $ruletable insert end $info
        }
#        rules_tab_selected_hack
    }
    
    method rules_tab_selected_hack {} {
	$ruletable start_motion 2 2
	$ruletable motion 2 3
	$ruletable resize 2 2
    }
    
    method cb_rule_togle {} {
        set tool_chain [$tChainCBX get]
        set tchain_obj [GetToolChainObject $tool_chain]

        set sel [$ruletable curselection]
        if {[$b_target GetRuleStatus $rulesindex($sel)]=="Enabled"} {
            $b_target SetRuleStatus $rulesindex($sel) "Disabled"
        } else {
            $b_target SetRuleStatus $rulesindex($sel) "Enabled"
        }

        SetBuildRules
	$ruletable selection set $sel
	HandleRuleTableState
    }

    method HandleRuleTableState {} {
        set tool_chain [$tChainCBX get]
        set tchain_obj [GetToolChainObject $tool_chain]

        set sel [$ruletable curselection]
        if {$sel==""} {
            # If nothing is selected then disable togle button.
            $ruledisen configure -state disabled
	    $ruleedit configure -state disabled
        } else {
            $ruledisen configure -state normal 
            $ruleedit configure -state normal
            if {[$b_target GetRuleStatus $rulesindex($sel)]=="Enabled"} {
               $ruledisen configure -text [get_indep String IDETEBuildRuleDisable] \
	                               -under [get_indep Pos IDETEBuildRuleDisable]
            } else {
               $ruledisen configure -text [get_indep String IDETEBuildRuleEnable] \
	                               -under [get_indep Pos IDETEBuildRuleEnable]
            }
        }
    }

    method ruletable_double_cb {} {
        set tool_chain [$tChainCBX get]
        set tchain_obj [GetToolChainObject $tool_chain]

        set sel [$ruletable curselection]
        DummyCreateToolChain_spec
	if {$NewTarget=="1"} {
	    #Don't generate the Auto Include paths again.
	    set NewTarget ""
	    $b_target SetAutoIncludes $rulesindex($sel) [GenerateIncludePaths $src_file_list]
	}
        set ttdlg [snIdeToolsDlg .toolchaindlg $tchain_obj $rulesindex($sel) $b_target]

        $ttdlg CreateDialog
	# Make sure the edit target dialog is still modal	
        grab_focus

	UpdateCmdLine
	HandleRuleTableState
    }

    method HandleLibsTabState {} {

	set selected [$libLBX curselect]
	if {$selected==""} {
	    $libadd configure -state normal
	    $libdel configure -state disabled
	    $libup configure -state disabled
	    $libdown configure -state disabled
	} else {
	    $libadd configure -state normal
	    $libdel configure -state normal

	    # If the 1st lib is selected disabled "Move up"
	    if {$selected=="0"} {
		$libup configure -state disabled
	    } else {
		$libup configure -state normal
	    }

	    # If the last lib is selected disabled "Move down"
	    set tmpsel $selected
	    incr tmpsel
	    if {$tmpsel==[$libLBX size]} {
		$libdown configure -state disabled
	    } else {
		$libdown configure -state normal
	    }
	}
    }

    method cb_double_click_lib {} {
	HandleLibsTabState
    }

    method cb_add_lib {} {
	set libfile [tk_getOpenFile]
	set tmpcmd "$libLBX insert end $libfile"
	eval $tmpcmd
	HandleLibsTabState
    }

    method cb_del_lib {} {
	set selected [$libLBX curselect]
	$libLBX delete $selected
	HandleLibsTabState
    }

    method cb_up_lib {} {
	set selected [$libLBX curselect]
	set libfile [$libLBX get $selected]
	$libLBX delete $selected
	set selected [expr "$selected - 1"]
	$libLBX insert $selected $libfile
	$libLBX selection set $selected
	HandleLibsTabState
    }

    method cb_down_lib {} {
	set selected [$libLBX curselect]
	set libfile [$libLBX get $selected]
	$libLBX delete $selected
	incr selected
	$libLBX insert $selected $libfile
	$libLBX selection set $selected
	HandleLibsTabState
    }

    method ok_cb {} {

        #TODO: check form is completed enough

	# Generate the Auto include paths if it has been done yet.
	if {$NewTarget=="1"} {
	    #Don't generate the Auto Include paths again.
	    set NewTarget ""
            set sel [$ruletable curselection]
	    DummyCreateToolChain_spec
	    $b_target SetAutoIncludes $rulesindex($sel) [GenerateIncludePaths $src_file_list]
	}

        SaveData

        DestroyDialog

    }

    method SaveData {} {
        #Write Data to build target object

        SetBuildDirectory [$bDirLEB.txt get]
        SetToolChain [$tChainCBX get]
        SetTargetType [$tTypeCBX get]
	
        # Pass "none" if no libraries are listed.
        if {[$libLBX get 0 end]==""} {
	    SetLibraryFiles none
	} else {
            SetLibraryFiles [$libLBX get 0 end]
        }
	
	SetOutputFilename [$linkFilenameEntry get]

        # Pass "%none%" if no entry point.
	if {[$entryPointEntry get]==""} {
	    SetLinkerEntryPoint "%none%"
	} else {
	    SetLinkerEntryPoint [$entryPointEntry get]
	}

        # Pass "%none%" if no user flags.
        if {[$linkUserFlagsEntry get]==""} {
	    SetUserLinkFlags "%none%"
	} else {
            SetUserLinkFlags [$linkUserFlagsEntry get]
        }
	
	# Save Launch command line
	$b_target SetLaunchCommandLine [$execCmdEntry get]
	
	# Save linker tool
	SetLinkerExecutable [$linkExecLEB.txt get]

        $b_target SaveData
    }

    method cancel_cb {} {

        DestroyDialog
    }


    method DestroyDialog {} {
        global tkPriv
        $b_target delete
        $bDirLEB delete
	$linkExecLEB delete
	$ruletable delete
        destroy $thisTail
        set tkPriv($thisTail,button) "1" 
    }

}


