# ------------------------------------------------------------------------------
#  checkframe.tcl
#  This file is add as part of Unifix BWidget Toolkit --- by Jigen Zhou
# ------------------------------------------------------------------------------
#  Index of commands:
#     - CheckFrame::create
#     - CheckFrame::configure
#     - CheckFrame::cget
#     - CheckFrame::getframe
#     - CheckFrame::actframe
#     - CheckFrame::_place
# ------------------------------------------------------------------------------

namespace eval CheckFrame {
    Widget::declare CheckFrame {
        {-relief      TkResource groove 0 frame}
        {-borderwidth TkResource 2      0 frame}
        {-font        TkResource ""     0 label}
        {-foreground  TkResource ""     0 label}
        {-state       TkResource ""     0 label}
        {-background  TkResource ""     0 frame}
        {-text        String     ""     0}
        {-variable    String     ""     0}
        {-command     String     ""     0}
        {-ipad        Int        4      0 "%d >=0"}
        {-side        Enum       left   0 {left center right}}
        {-baseline    Enum       center 0 {top center bottom}}
        {-fg          Synonym    -foreground}
        {-bg          Synonym    -background}
        {-bd          Synonym    -borderwidth}
    }

    Widget::addmap CheckFrame "" :cmd {-background {}}
    Widget::addmap CheckFrame "" .l   {-background {} -foreground {} -text {} -font {}}
    Widget::addmap CheckFrame "" .p   {-background {}}
    Widget::addmap CheckFrame "" .b   {-background {} -relief {} -borderwidth {}}
    Widget::addmap CheckFrame "" .b.p {-background {}}
    Widget::addmap CheckFrame "" .f   {-background {}}

    proc ::CheckFrame { path args } { return [eval CheckFrame::create $path $args] }
    proc use {} {}
}


# ------------------------------------------------------------------------------
#  Command CheckFrame::create
# ------------------------------------------------------------------------------
proc CheckFrame::create { path args } {
    Widget::init CheckFrame $path $args

    set frame  [eval frame $path [Widget::subcget $path :cmd] \
	    -class CheckFrame -relief flat -bd 0 -highlightthickness 0]

    set padtop [eval frame $path.p [Widget::subcget $path :cmd] \
	    -relief flat -borderwidth 0]
    set border [eval frame $path.b [Widget::subcget $path .b] -highlightthickness 0]

    set check  [eval checkbutton $path.l [Widget::subcget $path .l] \
                     -highlightthickness 0 -relief flat \
                     -bd     2 -padx 2 -pady 0]

    set var [Widget::getMegawidgetOption $path -variable]
    set cmd [Widget::getMegawidgetOption $path -command]
    set st  [Widget::getMegawidgetOption $path -state]
    $check configure -variable $var -state $st \
                -command "CheckFrame::actframe $path; $cmd"

    set padbot [eval frame $border.p [Widget::subcget $path .p] \
	    -relief flat -bd 0 -highlightthickness 0]
    set frame  [eval frame $path.f [Widget::subcget $path .f] \
	    -relief flat -bd 0 -highlightthickness 0]
    set height [winfo reqheight $check]

    switch [Widget::getoption $path -side] {
        left   { set relx 0.0; set x 5;  set anchor nw }
        center { set relx 0.5; set x 0;  set anchor n  }
        right  { set relx 1.0; set x -5; set anchor ne }
    }
    set bd [Widget::getoption $path -borderwidth]
    switch [Widget::getoption $path -baseline] {
        top    { set htop $height; set hbot 1; set y 0 }
        center { set htop [expr {$height/2}]; set hbot [expr {$height/2+$height%2+1}]; set y 0 }
        bottom { set htop 1; set hbot $height; set y [expr {$bd+1}] }
    }
    $padtop configure -height $htop
    $padbot configure -height $hbot

    set pad [Widget::getoption $path -ipad]
    pack $padbot -side top -fill x
    pack $frame  -in $border -fill both -expand yes -padx $pad -pady $pad

    pack $padtop -side top -fill x
    pack $border -fill both -expand yes

    place $check -relx $relx -x $x -anchor $anchor -y $y

    bind $check <Configure> "CheckFrame::_place $path"
    bind $path  <Destroy>   {Widget::destroy %W; rename %W {}}

    rename $path ::$path:cmd
    proc ::$path { cmd args } "return \[eval CheckFrame::\$cmd $path \$args\]"
    
    return $path
}


# ------------------------------------------------------------------------------
#  Command CheckFrame::configure
# ------------------------------------------------------------------------------
proc CheckFrame::configure { path args } {
    set res [Widget::configure $path $args]

    if { [Widget::hasChanged $path -command cmd] } {
       $path.l configure -command "CheckFrame::actframe $path; $cmd"
    }
    if { [Widget::hasChanged $path -variable var] } {
       $path.l configure -variable $var
    }
    if { [Widget::hasChanged $path -state st] } {
       $path.l configure -state $st
    }
    if { [Widget::hasChanged $path -ipad pad] } {
        pack configure $path.f -padx $pad -pady $pad
    }
    if { [Widget::hasChanged $path -borderwidth val] |
         [Widget::hasChanged $path -font        val] |
         [Widget::hasChanged $path -side        val] |
         [Widget::hasChanged $path -baseline    val] } {
        _place $path
    }

    return $res
}


# ------------------------------------------------------------------------------
#  Command CheckFrame::cget
# ------------------------------------------------------------------------------
proc CheckFrame::cget { path option } {
    return [Widget::cget $path $option]
}


# ------------------------------------------------------------------------------
#  Command CheckFrame::getframe
# ------------------------------------------------------------------------------
proc CheckFrame::getframe { path } {
    return $path.f
}

# ------------------------------------------------------------------------------
#  Command CheckFrame::actframe_recur
# ------------------------------------------------------------------------------
proc CheckFrame::actframe_recur {w st} {
   if ![winfo exist $w] {return ""}
   switch -- [winfo class $w] {
      Button - Label - Entry - Text - Scale \
             - Checkbutton - Radiobutton - Menubutton - ListBox - ComboBox \
             - LabelEntry - LabelFrame - CheckFrame - RadioFrame \
             - SelectColorMenu - SpinBox - TitleFrame - Tree {
         $w configure -state $st
      }
      Listbox {
      }
   }
   foreach s [winfo children $w] { CheckFrame::actframe_recur $s $st }
}

# ------------------------------------------------------------------------------
#  Command CheckFrame::actframe
# ------------------------------------------------------------------------------
proc CheckFrame::actframe { path } {
   set st normal
   set val [set [Widget::cget $path -variable]]
   if {!$val} {set st disabled}

   actframe_recur $path.f $st
}

# ------------------------------------------------------------------------------
#  Command CheckFrame::_place
# ------------------------------------------------------------------------------
proc CheckFrame::_place { path } {
    set height [winfo height $path.l]
    switch [Widget::getoption $path -side] {
        left    { set relx 0.0; set x 10;  set anchor nw }
        center  { set relx 0.5; set x 0;   set anchor n  }
        right   { set relx 1.0; set x -10; set anchor ne }
    }
    set bd [Widget::getoption $path -borderwidth]
    switch [Widget::getoption $path -baseline] {
        top    { set htop $height; set hbot 1; set y 0 }
        center { set htop [expr {$height/2}]; set hbot [expr {$height/2+$height%2+1}]; set y 0 }
        bottom { set htop 1; set hbot $height; set y [expr {$bd+1}] }
    }
    $path.p   configure -height $htop
    $path.b.p configure -height $hbot

    place $path.l -relx $relx -x $x -anchor $anchor -y $y
}




