

#-----------------------------------------------------
#------ Procedures -----------------------------------
#-----------------------------------------------------

proc proceed [] {
    global type

    if {$type == 1} {
		displayType1
    } elseif {$type == 2} {
		displayType2
    } elseif {$type == 3} {
		displayType3
    }
}


proc displayType1 [] {
    destroyWindows2

    frame .type1
    pack  .type1 -expand 1 -fill both

    frame .type1.up -relief groove -bd 1
    frame .type1.down -relief groove -bd 1
    pack  .type1.up .type1.down -expand 1 -fill both

    frame .type1.up.frame
    frame .type1.down.frame
    pack  .type1.up.frame .type1.down.frame

    frame .type1.up.frame.left
    frame .type1.up.frame.right
    pack  .type1.up.frame.left .type1.up.frame.right -side left

    frame .type1.up.frame.left.l0
    frame .type1.up.frame.left.l1
    pack  .type1.up.frame.left.l0 .type1.up.frame.left.l1 -anchor w -expand 1 -fill x

    label .type1.up.frame.left.l0.label -text "GAP variable:"
    label .type1.up.frame.left.l1.label -text "Number of generators:"
    pack  .type1.up.frame.left.l0.label .type1.up.frame.left.l1.label -anchor w

    frame .type1.up.frame.right.l0
    frame .type1.up.frame.right.l1
    pack  .type1.up.frame.right.l0 .type1.up.frame.right.l1 -anchor w

    entry .type1.up.frame.right.l0.entry -width 8
    entry .type1.up.frame.right.l1.entry -width 8
    pack  .type1.up.frame.right.l0.entry .type1.up.frame.right.l1.entry

    button .type1.down.frame.proceedt1 -command proceedt1 -text Proceed
    pack   .type1.down.frame.proceedt1 -padx 2 -pady 2

    bind .type1.up.frame.right.l0.entry <Return> {.type1.down.frame.proceedt1 invoke}
    bind .type1.up.frame.right.l1.entry <Return> {.type1.down.frame.proceedt1 invoke}
    bind .type1.down.frame.proceedt1 <Return> {.type1.down.frame.proceedt1 invoke}

    focus .type1.up.frame.right.l0.entry
}


proc displayType2 [] {
    destroyWindows2

    frame .type2
    pack  .type2 -expand 1 -fill both

	frame .type2.up0 -relief groove -bd 1
    frame .type2.up -relief groove -bd 1
    frame .type2.down -relief groove -bd 1
    pack  .type2.up0 .type2.up .type2.down -expand 1 -fill both

    frame .type2.up0.frame
    frame .type2.up.frame
    frame .type2.down.frame
    pack  .type2.up0.frame .type2.up.frame .type2.down.frame

	label .type2.up0.frame.label -text "modular numerical semigroup satisfying ax mod b <= x"
	pack  .type2.up0.frame.label

    frame .type2.up.frame.left
    frame .type2.up.frame.right
    pack  .type2.up.frame.left .type2.up.frame.right -side left

    frame .type2.up.frame.left.l0
    frame .type2.up.frame.left.l1
    frame .type2.up.frame.left.l2
    pack  .type2.up.frame.left.l0 .type2.up.frame.left.l1 .type2.up.frame.left.l2 -anchor w -expand 1 -fill x

    label .type2.up.frame.left.l0.label -text "GAP variable:"
    label .type2.up.frame.left.l1.label -text "a:"
    label .type2.up.frame.left.l2.label -text "b:"
    pack  .type2.up.frame.left.l0.label .type2.up.frame.left.l1.label .type2.up.frame.left.l2.label -anchor w

    frame .type2.up.frame.right.l0
    frame .type2.up.frame.right.l1
    frame .type2.up.frame.right.l2
    pack  .type2.up.frame.right.l0 .type2.up.frame.right.l1 .type2.up.frame.right.l2 -anchor w

    entry .type2.up.frame.right.l0.entry -width 8
    entry .type2.up.frame.right.l1.entry -width 8
    entry .type2.up.frame.right.l2.entry -width 8
    pack  .type2.up.frame.right.l0.entry .type2.up.frame.right.l1.entry .type2.up.frame.right.l2.entry

    button .type2.down.frame.proceedt2 -command proceedt2 -text Proceed
    pack   .type2.down.frame.proceedt2 -padx 2 -pady 2

    bind .type2.up.frame.right.l0.entry <Return> {.type2.down.frame.proceedt2 invoke}
    bind .type2.up.frame.right.l1.entry <Return> {.type2.down.frame.proceedt2 invoke}
    bind .type2.up.frame.right.l2.entry <Return> {.type2.down.frame.proceedt2 invoke}
    bind .type2.down.frame.proceedt2 <Return> {.type2.down.frame.proceedt2 invoke}

    focus .type2.up.frame.right.l0.entry
}




proc displayType3 [] {
	destroyWindows2

    frame .type3
    pack  .type3 -expand 1 -fill both

	frame .type3.up0 -relief groove -bd 1
    frame .type3.up -relief groove -bd 1
    frame .type3.down -relief groove -bd 1
    pack  .type3.up0 .type3.up .type3.down -expand 1 -fill both

    frame .type3.up0.frame
    frame .type3.up.frame
    frame .type3.down.frame
    pack  .type3.up0.frame .type3.up.frame .type3.down.frame

	label .type3.up0.frame.label -text "proportionally modular numerical semigroup satisfying ax mod b <= cx"
	pack  .type3.up0.frame.label

    frame .type3.up.frame.left
    frame .type3.up.frame.right
    pack  .type3.up.frame.left .type3.up.frame.right -side left

    frame .type3.up.frame.left.l0
    frame .type3.up.frame.left.l1
    frame .type3.up.frame.left.l2
    frame .type3.up.frame.left.l3
    pack  .type3.up.frame.left.l0 .type3.up.frame.left.l1 .type3.up.frame.left.l2 .type3.up.frame.left.l3 -anchor w -expand 1 -fill x

    label .type3.up.frame.left.l0.label -text "GAP variable:"
    label .type3.up.frame.left.l1.label -text "a:"
    label .type3.up.frame.left.l2.label -text "b:"
    label .type3.up.frame.left.l3.label -text "c:"
    pack  .type3.up.frame.left.l0.label .type3.up.frame.left.l1.label .type3.up.frame.left.l2.label .type3.up.frame.left.l3.label -anchor w

    frame .type3.up.frame.right.l0
    frame .type3.up.frame.right.l1
    frame .type3.up.frame.right.l2
    frame .type3.up.frame.right.l3
    pack  .type3.up.frame.right.l0 .type3.up.frame.right.l1 .type3.up.frame.right.l2 .type3.up.frame.right.l3 -anchor w

    entry .type3.up.frame.right.l0.entry -width 8
    entry .type3.up.frame.right.l1.entry -width 8
    entry .type3.up.frame.right.l2.entry -width 8
    entry .type3.up.frame.right.l3.entry -width 8
    pack  .type3.up.frame.right.l0.entry .type3.up.frame.right.l1.entry .type3.up.frame.right.l2.entry .type3.up.frame.right.l3.entry

    button .type3.down.frame.proceedt3 -command proceedt3 -text Proceed
    pack   .type3.down.frame.proceedt3 -padx 2 -pady 2

    bind .type3.up.frame.right.l0.entry <Return> {.type3.down.frame.proceedt3 invoke}
    bind .type3.up.frame.right.l1.entry <Return> {.type3.down.frame.proceedt3 invoke}
    bind .type3.up.frame.right.l2.entry <Return> {.type3.down.frame.proceedt3 invoke}
    bind .type3.up.frame.right.l3.entry <Return> {.type3.down.frame.proceedt3 invoke}
    bind .type3.down.frame.proceedt3 <Return> {.type3.down.frame.proceedt3 invoke}

    focus .type3.up.frame.right.l0.entry
}


#-----------------------------------------------------
#------ Proceed --------------------------------------
#-----------------------------------------------------

proc proceedt1 [] {

    destroyWindows

    set var   [.type1.up.frame.right.l0.entry get]
    set ngens [.type1.up.frame.right.l1.entry get]

    if {$var == ""} {
	error "Please specify the GAP variable\n to which the semigroup will be associated"
    }
    if {[string is integer $var]} {
	error "The GAP variable must be a string,\n not an integer"
    }
    if {![string is integer $ngens] || $ngens > 26 || $ngens < 1} {
	error "The number of generators must be\n a positive integer less than 27"
    }

    frame .type12 -relief groove -bd 1
    pack  .type12 -expand 1 -fill both
    frame .type12.frame
    pack  .type12.frame

    frame .type12.frame.left
    frame .type12.frame.right
    pack  .type12.frame.left .type12.frame.right -side left -anchor n -expand 1 -fill y

    label .type12.frame.left.label -text "Generators: "
    pack  .type12.frame.left.label

    frame .type12.down -relief groove -bd 1
    pack  .type12.down -expand 1 -fill both
    frame .type12.down.frame
    pack  .type12.down.frame

    button .type12.down.frame.another  -command another12 -text "Another generator"
    button .type12.down.frame.done  -command done12 -text "Done"

    bind .type12.down.frame.another <Return> {.type12.down.frame.another invoke}
    bind .type12.down.frame.done <Return> {.type12.down.frame.done invoke}

    menubutton .type12.down.frame.functions -text Functions -menu .type12.down.frame.functions.menu -takefocus 1

    pack .type12.down.frame.functions .type12.down.frame.another .type12.down.frame.done -padx 2 -pady 2 -side left

    menu .type12.down.frame.functions.menu


    .type12.down.frame.functions.menu add command -label "Add a function to this menu" -command "addFunc 1"
    .type12.down.frame.functions.menu add command -label "Remove an added function" -command "remFunc 1"
    .type12.down.frame.functions.menu add separator


    .type12.down.frame.functions.menu add command -label "Apery list" -command "aperyList 1"
    .type12.down.frame.functions.menu add command -label "Draw Apery list" -command "drawAperyList 1"
    .type12.down.frame.functions.menu add command -label "Frobenius number" -command "frobeniusNumber 1"
    .type12.down.frame.functions.menu add command -label "Gaps" -command "doGaps 1"
    .type12.down.frame.functions.menu add command -label "Minimal presentation" -command "minimalPresentation 1"
    .type12.down.frame.functions.menu add command -label "Small elements" -command "smallElements 1"

	.type12.down.frame.functions.menu add separator

	set fl [open "xnumsemi_new_funcs.tcl.menu1" r]
    set cmd [read $fl]
    eval $cmd
    if {[catch {close $fl} err]} {
    }

    for {set i 1} {$i <= $ngens} {incr i 1} {
		insertGenerator $i
    }

    focus .type12.frame.right.e1
}


proc proceedt2 [] {

    destroyWindows

    set var   [.type2.up.frame.right.l0.entry get]
    set a	[.type2.up.frame.right.l1.entry get]
    set b	[.type2.up.frame.right.l2.entry get]

    if {$var == ""} {
		error "Please specify the GAP variable\n to which the semigroup will be associated"
    }
    if {[string is integer $var]} {
		error "The GAP variable must be a string,\n not an integer"
    }
    if {![string is integer $a] || $a < 0} {
		error "<a> must be a positive integer"
    }
    if {![string is integer $b] || $b < 0} {
		error "<b> must be a positive integer"
    }


    frame .type22 -relief groove -bd 1
    pack  .type22 -expand 1 -fill both
    frame .type22.frame
    pack  .type22.frame

    frame .type22.down -relief groove -bd 1
    pack  .type22.down -expand 1 -fill both
    frame .type22.down.frame
    pack  .type22.down.frame

    button .type22.down.frame.done  -command done22 -text "Done"

    bind .type22.down.frame.done <Return> {.type22.down.frame.done invoke}

    menubutton .type22.down.frame.functions -text Functions -menu .type22.down.frame.functions.menu -takefocus 1

    pack .type22.down.frame.functions .type22.down.frame.done -padx 2 -pady 2 -side left

    menu .type22.down.frame.functions.menu

    .type22.down.frame.functions.menu add command -label "Add a function to this menu" -command "addFunc 2"
	.type22.down.frame.functions.menu add command -label "Remove an added function" -command "remFunc 2"

    .type22.down.frame.functions.menu add separator

	.type22.down.frame.functions.menu add command -label "Apery list" -command "aperyList 2"
    .type22.down.frame.functions.menu add command -label "Draw Apery list" -command "drawAperyList 2"
    .type22.down.frame.functions.menu add command -label "Frobenius number" -command "frobeniusNumber 2"
    .type22.down.frame.functions.menu add command -label "Gaps" -command "doGaps 2"
    .type22.down.frame.functions.menu add command -label "Minimal presentation" -command "minimalPresentation 2"
    .type22.down.frame.functions.menu add command -label "Small elements" -command "smallElements 2"

	.type22.down.frame.functions.menu add separator

	set fl [open "xnumsemi_new_funcs.tcl.menu2" r]
    set cmd [read $fl]
    eval $cmd
    if {[catch {close $fl} err]} {
    }

}



proc proceedt3 [] {
    destroyWindows

    set var   [.type3.up.frame.right.l0.entry get]
    set a	[.type3.up.frame.right.l1.entry get]
    set b	[.type3.up.frame.right.l2.entry get]
    set c	[.type3.up.frame.right.l3.entry get]

    if {$var == ""} {
		error "Please specify the GAP variable\n to which the semigroup will be associated"
    }
    if {[string is integer $var]} {
		error "The GAP variable must be a string,\n not an integer"
    }
    if {![string is integer $a] || $a < 0} {
		error "<a> must be a positive integer"
    }
    if {![string is integer $b] || $b < 0} {
		error "<b> must be a positive integer"
    }
	if {![string is integer $c] || $c < 0} {
		error "<c> must be a positive integer"
    }


    frame .type32 -relief groove -bd 1
    pack  .type32 -expand 1 -fill both
    frame .type32.frame
    pack  .type32.frame

    frame .type32.down -relief groove -bd 1
    pack  .type32.down -expand 1 -fill both
    frame .type32.down.frame
    pack  .type32.down.frame

    button .type32.down.frame.done  -command done32 -text "Done"

    bind .type32.down.frame.done <Return> {.type32.down.frame.done invoke}

    menubutton .type32.down.frame.functions -text Functions -menu .type32.down.frame.functions.menu -takefocus 1

    pack .type32.down.frame.functions .type32.down.frame.done -padx 2 -pady 2 -side left

    menu .type32.down.frame.functions.menu

    .type32.down.frame.functions.menu add command -label "Add a function to this menu" -command "addFunc 3"
.type32.down.frame.functions.menu add command -label "Remove an added function" -command "remFunc 3"

    .type32.down.frame.functions.menu add separator

	.type32.down.frame.functions.menu add command -label "Apery list" -command "aperyList 3"
    .type32.down.frame.functions.menu add command -label "Draw Apery list" -command "drawAperyList 3"
    .type32.down.frame.functions.menu add command -label "Frobenius number" -command "frobeniusNumber 3"
    .type32.down.frame.functions.menu add command -label "Gaps" -command "doGaps 3"
    .type32.down.frame.functions.menu add command -label "Minimal presentation" -command "minimalPresentation 3"
    .type32.down.frame.functions.menu add command -label "Small elements" -command "smallElements 3"

	.type32.down.frame.functions.menu add separator

	set fl [open "xnumsemi_new_funcs.tcl.menu3" r]
    set cmd [read $fl]
    eval $cmd
    if {[catch {close $fl} err]} {
    }

}



#-----------------------------------------------------
#------ Another --------------------------------------
#-----------------------------------------------------

proc another12 [] {
    set ngens [.type1.up.frame.right.l1.entry get]

    .type1.up.frame.right.l1.entry delete 0 [string length $ngens]
    incr ngens 1
    .type1.up.frame.right.l1.entry insert 0 $ngens

    set e1 [insertGenerator $ngens]
    focus $e1
}

#-----------------------------------------------------
#------ Insert Another -------------------------------
#-----------------------------------------------------

proc insertGenerator {i} {

    set line [format "e%i" $i]
    set cmd ""
	append cmd ".type12.frame.right." $line
    entry $cmd
    pack $cmd -side left
    eval "$cmd configure -width 3"
	bind $cmd <Return> {.type12.down.frame.done invoke}
	return $cmd
}




#-----------------------------------------------------
#------ Done -----------------------------------------
#-----------------------------------------------------

proc done12 [] {
    set var   [.type1.up.frame.right.l0.entry get]
    set ngens [.type1.up.frame.right.l1.entry get]

	set str "$var:=XNumericalSemigroupByGenerators("
    for {set i 1} {$i <= $ngens} {incr i 1} {
	    set obj [format ".type12.frame.right.e%i" $i]
	    set val [$obj get]
	    if {![string is integer $val] || $val < 1} {
			error "The generators must be positive integers"
	    }
	    if {$i == 1} {
			append str $val
	    } else {
			append str "," $val
	    }
	}
    append str ");"
    puts $str
    puts "end"
}


proc done22 [] {
    set var   [.type2.up.frame.right.l0.entry get]
    set a [.type2.up.frame.right.l1.entry get]
    set b [.type2.up.frame.right.l2.entry get]

	set str "$var:=ModularNumericalSemigroup($a, $b);"
    puts $str
    puts "end"
}


proc done32 [] {
    set var   [.type3.up.frame.right.l0.entry get]
    set a [.type3.up.frame.right.l1.entry get]
    set b [.type3.up.frame.right.l2.entry get]
    set c [.type3.up.frame.right.l3.entry get]

	set str "$var:=ProportionallyModularNumericalSemigroup($a, $b, $c);"
    puts $str
    puts "end"
}



#-----------------------------------------------------
#------ Functions ------------------------------------
#-----------------------------------------------------

proc addFunc {var} {

    if {[winfo exists .addfunc]} {
	destroy .addfunc
    }
    toplevel .addfunc

    frame .addfunc.frame
    pack  .addfunc.frame

    frame .addfunc.frame.top
    frame .addfunc.frame.bot
    pack  .addfunc.frame.top .addfunc.frame.bot

    frame .addfunc.frame.top.left
    frame .addfunc.frame.top.right
    pack  .addfunc.frame.top.left .addfunc.frame.top.right -side left

    label .addfunc.frame.top.left.label -text "Function name:"
    pack  .addfunc.frame.top.left.label

    entry .addfunc.frame.top.right.entry -width 40
    pack  .addfunc.frame.top.right.entry

    button .addfunc.frame.bot.ok -command "doneaddFunc $var" -text Ok
    pack   .addfunc.frame.bot.ok -padx 2 -pady 2

    bind .addfunc.frame.top.right.entry <Return> {.addfunc.frame.bot.ok invoke}
    bind .addfunc.frame.bot.ok <Return> {.addfunc.frame.bot.ok invoke}

    focus .addfunc.frame.top.right.entry
}

proc doneaddFunc {var} {
    global new_funcs


    set name   [.addfunc.frame.top.right.entry get]

    set len [string length $name]

    for {set i 0} {$i < $len} {incr i} {
	set c [string index $name $i]
	if {$c == " " } {
	    error "The function's name must contain no spaces"
	    return
	}
    }

    set fl [open "xnumsemi_new_funcs.tcl.procs" a]
    set str "proc $name {var} {\ninvokeDone\nset obj \[\".type\$var.up.frame.right.l0.entry\" get\]\nputs \"$name"
    append str "(\$obj);\"\nputs \"end\"   \n}\n"
    puts $fl $str
    if {[catch {close $fl} err]} {
    }
    eval $str

    set fl [open "xnumsemi_new_funcs.tcl.menu1" a]
    set str ".type12.down.frame.functions.menu add command -label \"$name\" -command \"$name 1\""
    puts $fl $str
    if {[catch {close $fl} err]} {
    }
    if {$var == 1} {
	eval $str
    }

    set fl [open "xnumsemi_new_funcs.tcl.menu2" a]
    set str ".type22.down.frame.functions.menu add command -label \"$name\" -command \"$name 2\""
    puts $fl $str
    if {[catch {close $fl} err]} {
    }
    if {$var == 2} {
	eval $str
    }

    set fl [open "xnumsemi_new_funcs.tcl.menu3" a]
    set str ".type32.down.frame.functions.menu add command -label \"$name\" -command \"$name 3\""
    puts $fl $str
    if {[catch {close $fl} err]} {
    }
    if {$var == 3} {
	eval $str
    }

    set fl [open "xnumsemi_new_funcs.tcl.names" a]
    puts $fl $name
    if {[catch {close $fl} err]} {
    }
    lappend new_funcs $name

    set new_list []
    foreach {name} $new_funcs {
	if {$name != ""} {
	    lappend new_list $name
}
}
    set new_funcs $new_list

    destroy .addfunc
}


proc remFunc {var} {
    global new_funcs

    if {[winfo exists .remfunc]} {
	destroy .remfunc
    }
    toplevel .remfunc

    frame .remfunc.frame
    pack  .remfunc.frame

    frame .remfunc.frame.top
    frame .remfunc.frame.bot
    pack  .remfunc.frame.top .remfunc.frame.bot

    listbox .remfunc.frame.top.listbox
    pack .remfunc.frame.top.listbox

    foreach {name} $new_funcs {
	.remfunc.frame.top.listbox insert end $name
    }


    button .remfunc.frame.bot.ok -command "doneremFunc $var" -text Ok
    pack   .remfunc.frame.bot.ok -padx 2 -pady 2

    bind .remfunc.frame.bot.ok <Return> {.remfunc.frame.bot.ok invoke}

}


proc doneremFunc {var} {
    global new_funcs

    set inds   [.remfunc.frame.top.listbox curselection]

    foreach {i} $inds {
	lset new_funcs $i ""
	set rind [expr 11 + $i]
	if {$var == 3} {
	    set str ".type$var.down.frame.functions.menu delete $rind"
	} else {
	    set str ".type$var"
	    append str "2.down.frame.functions.menu delete $rind"
	}
	eval $str
    }
    set new_list []
    foreach {name} $new_funcs {
	if {$name != ""} {
	    lappend new_list $name
	}
    }
    set new_funcs $new_list

    rebuild_new_funcs $var

    destroy .remfunc
}

proc rebuild_new_funcs {var} {
    global new_funcs

    set fl [open "xnumsemi_new_funcs.tcl.names" w]
    close $fl
    set fl [open "xnumsemi_new_funcs.tcl.procs" w]
    close $fl
    set fl [open "xnumsemi_new_funcs.tcl.menu1" w]
    close $fl
    set fl [open "xnumsemi_new_funcs.tcl.menu2" w]
    close $fl
    set fl [open "xnumsemi_new_funcs.tcl.menu3" w]
    close $fl



    foreach {name} $new_funcs {
	set fl [open "xnumsemi_new_funcs.tcl.procs" a]
	set str "proc $name {var} {\ninvokeDone\nset obj \[\".type\$var.up.frame.right.l0.entry\" get\]\nputs \"$name"
	append str "(\$obj);\"\nputs \"end\"   \n}\n"
	puts $fl $str
	if {[catch {close $fl} err]} {
	}
	eval $str

	set fl [open "xnumsemi_new_funcs.tcl.menu1" a]
	set str ".type12.down.frame.functions.menu add command -label \"$name\" -command \"$name 1\""
	puts $fl $str
	if {[catch {close $fl} err]} {
	}

	set fl [open "xnumsemi_new_funcs.tcl.menu2" a]
	set str ".type22.down.frame.functions.menu add command -label \"$name\" -command \"$name 2\""
	puts $fl $str
	if {[catch {close $fl} err]} {
	}

	set fl [open "xnumsemi_new_funcs.tcl.menu3" a]
	set str ".type3.down.frame.functions.menu add command -label \"$name\" -command \"$name 3\""
	puts $fl $str
	if {[catch {close $fl} err]} {
	}

	set fl [open "xnumsemi_new_funcs.tcl.names" a]
	puts $fl $name
	if {[catch {close $fl} err]} {
	}

    }

}


#-----------------------------------------------------
#------ Predefined functions of menu -----------------
#-----------------------------------------------------
proc aperyList {var} {
    # New top level window to input element
    toplevel .dialog
    frame .dialog.frame
    pack  .dialog.frame
    frame .dialog.frame.top
    frame .dialog.frame.mid
    frame .dialog.frame.bot
    pack  .dialog.frame.top .dialog.frame.mid .dialog.frame.bot

    frame .dialog.frame.top.left
    frame .dialog.frame.top.right
    pack  .dialog.frame.top.left .dialog.frame.top.right -side left

    label .dialog.frame.top.left.label -text "Element of the numerical semigroup: "
    pack  .dialog.frame.top.left.label

    entry .dialog.frame.top.right.entry -width 4
    pack  .dialog.frame.top.right.entry

    label .dialog.frame.mid.label -text "          ----------------          " -relief groove -bd 2 -bg aquamarine2
    pack  .dialog.frame.mid.label

	button .dialog.frame.bot.cancel -command "destroy .dialog" -text Cancel
    button .dialog.frame.bot.ok -command "doneDialog $var" -text Ok
    pack   .dialog.frame.bot.cancel .dialog.frame.bot.ok -side left -padx 2 -pady 2

    bind .dialog.frame.top.right.entry <Return> {.dialog.frame.bot.ok invoke}
    focus .dialog.frame.top.right.entry
}

proc doneDialog {var} {
    set obj [".type$var.up.frame.right.l0.entry" get]
    set el [.dialog.frame.top.right.entry get]
    if {![string is integer $el] || $el < 0} {
		error "The element must be a positive integer"
    }
    invokeDone
    destroy .dialog
    puts "XAperyListOfNumericalSemigroupWRTElement($obj, $el);"
    puts "end"
}


proc drawAperyList {var} {
	# New top level window to input element
    toplevel .dialog
    frame .dialog.frame
    pack  .dialog.frame
    frame .dialog.frame.top
    frame .dialog.frame.mid
    frame .dialog.frame.bot
    pack  .dialog.frame.top .dialog.frame.mid .dialog.frame.bot

    frame .dialog.frame.top.left
    frame .dialog.frame.top.right
    pack  .dialog.frame.top.left .dialog.frame.top.right -side left

    label .dialog.frame.top.left.label -text "Element of the numerical semigroup: "
    pack  .dialog.frame.top.left.label

    entry .dialog.frame.top.right.entry -width 4
    pack  .dialog.frame.top.right.entry

    label .dialog.frame.mid.label -text "          ----------------          " -relief groove -bd 2 -bg aquamarine2
    pack  .dialog.frame.mid.label

	button .dialog.frame.bot.cancel -command "destroy .dialog" -text Cancel
    button .dialog.frame.bot.ok -command "doneDialogDraw $var" -text Ok
    pack   .dialog.frame.bot.cancel .dialog.frame.bot.ok -side left -padx 2 -pady 2

    bind .dialog.frame.top.right.entry <Return> {.dialog.frame.bot.ok invoke}
    focus .dialog.frame.top.right.entry
}

proc doneDialogDraw {var} {
    set obj [".type$var.up.frame.right.l0.entry" get]
    set el [.dialog.frame.top.right.entry get]
    if {![string is integer $el] || $el < 0} {
		error "The element must be a positive integer"
    }
    invokeDone
    destroy .dialog
    puts "XDrawAperyListOfNumericalSemigroup($obj, $el);"
    puts "end"
}



proc smallElements {var} {
    invokeDone
    set obj [".type$var.up.frame.right.l0.entry" get]
    puts "SmallElementsOfNumericalSemigroup($obj);"
    puts "end"
}

proc doGaps {var} {
    invokeDone
    set obj [".type$var.up.frame.right.l0.entry" get]
    puts "GapsOfNumericalSemigroup($obj);"
    puts "end"
}


proc frobeniusNumber {var} {
    invokeDone
    set obj [".type$var.up.frame.right.l0.entry" get]
    puts "FrobeniusNumberOfNumericalSemigroup($obj);"
    puts "end"
}


proc minimalPresentation {var} {
    invokeDone
    set obj [".type$var.up.frame.right.l0.entry" get]
    puts "MinimalPresentationOfNumericalSemigroup($obj);"
    puts "end"
}


proc invokeDone {} {
    global type

    if {$type == 1} {
	.type12.down.frame.done invoke
    } elseif {$type == 2} {
	.type22.down.frame.done invoke
    } elseif {$type == 3} {
	.type32.down.frame.done invoke
    }
}


#-----------------------------------------------------
#------ Destroy Windows ------------------------------
#-----------------------------------------------------

proc destroyWindows2 [] {

    if {[winfo exists .type1]} {
	destroy .type1
    }
    if {[winfo exists .type12]} {
	destroy .type12
    }
    if {[winfo exists .type2]} {
	destroy .type2
    }
    if {[winfo exists .type22]} {
	destroy .type22
    }
    if {[winfo exists .type3]} {
	destroy .type3
    }
    if {[winfo exists .type32]} {
	destroy .type32
    }
    if {[winfo exists .type4]} {
	destroy .type4
    }
    if {[winfo exists .type42]} {
	destroy .type42
    }
}


proc destroyWindows [] {

    if {[winfo exists .type12]} {
	destroy .type12
    }
    if {[winfo exists .type22]} {
	destroy .type22
    }
    if {[winfo exists .type32]} {
	destroy .type32
    }
    if {[winfo exists .type42]} {
	destroy .type42
    }
}


proc cancelS [] {
    puts "quit"
}



#-----------------------------------------------------
#------ Interface ------------------------------------
#-----------------------------------------------------

frame .up -relief groove -bd 1
frame .middle -relief groove -bd 1
frame .down -relief groove -bd 1
pack  .up .middle .down -expand 1 -fill both

frame .middle.frame
frame .down.frame
pack  .middle.frame .down.frame

label .up.label -text "    Please choose the way to specify the numerical semigroup    "
pack  .up.label

radiobutton .middle.frame.rb1 -variable type -value 1 -text "Generators" -justify left
.middle.frame.rb1 select
radiobutton .middle.frame.rb2 -variable type -value 2 -text "Modular numerical semigroup" -justify left
radiobutton .middle.frame.rb3 -variable type -value 3 -text "Proportionally modular numerical semigroup" -justify left
pack  .middle.frame.rb1 .middle.frame.rb2 .middle.frame.rb3 -anchor w

button .down.frame.proceed -command proceed -text Proceed
button .down.frame.cancel -command cancelS -text Quit
pack   .down.frame.proceed .down.frame.cancel -side left -padx 2 -pady 2


#-----------------------------------------------------
#------ Bindings -------------------------------------
#-----------------------------------------------------

bind .up <Destroy> {.down.frame.cancel invoke}
bind .down.frame.proceed <Return> {.down.frame.proceed invoke}
bind .down.frame.cancel <Return> {.down.frame.cancel invoke}


#-----------------------------------------------------
#------ Finalization/Initialization ------------------
#-----------------------------------------------------

wm title . "XNumericalSemigroup - GAP Interface"

set fl [open "xnumsemi_new_funcs.tcl.names" r]
set names [read $fl]
set new_funcs [split $names "\n"]
if {[catch {close $fl} err]} {
}



if {$argc > 0} {
    set var "Sn"
    set type [lindex $argv 0]

    if {$type == 1} {
		set ngens [lindex $argv 1]

		.middle.frame.rb1 select
		.down.frame.proceed invoke
		.type1.up.frame.right.l0.entry insert 0 $var
		.type1.up.frame.right.l1.entry insert 0 $ngens
		proceedt1
		for {set i 1} {$i <= $ngens} {incr i 1} {
			set obj [format ".type12.frame.right.e%i" $i]
	    	$obj insert 0 [lindex $argv [expr $i+1]]
		}
    } elseif {$type == 2} {
		set a [lindex $argv 1]
		set b [lindex $argv 2]

		.middle.frame.rb2 select
		.down.frame.proceed invoke
		.type2.up.frame.right.l0.entry insert 0 $var
		.type2.up.frame.right.l1.entry insert 0 $a
		.type2.up.frame.right.l2.entry insert 0 $b
		proceedt2
    } elseif {$type == 3} {
    	set a [lindex $argv 1]
		set b [lindex $argv 2]
		set c [lindex $argv 3]

		.middle.frame.rb3 select
		.down.frame.proceed invoke
		.type3.up.frame.right.l0.entry insert 0 $var
		.type3.up.frame.right.l1.entry insert 0 $a
		.type3.up.frame.right.l2.entry insert 0 $b
		.type3.up.frame.right.l3.entry insert 0 $c
		proceedt3
    }
}

#--------------------------------------
# Read procs of user defined functions
#--------------------------------------
set fl [open "xnumsemi_new_funcs.tcl.procs" r]
set cmd [read $fl]
eval $cmd
if {[catch {close $fl} err]} {
}

