'
' This is a BaCon port of my GTK-server Calculator program using Glade.
'
' Compile this program as follows:
'
'  Using GCC: bacon -o -export-dynamic calc.bac
'  Using TCC: bacon -c tcc -o -rdynamic calc.bac
'
' (c) PvE, March 2010 - GPL.
'
' 1.0 - Initial release
' 1.1 - Compatibility with BaCon 1.0 build 10 and higher
' 1.2 - Adapted for BaCon 3.0 and higher
'--------------------------------------------------------------------------------------

' Get glade
INCLUDE "glade.bac"

' Export dynamic symbols
PRAGMA LDFLAGS -export-dynamic

' Some GTK calls
IMPORT "gtk_button_get_label(long)" FROM "libgtk-x11-2.0.so.0" TYPE char*
IMPORT "gtk_entry_get_text(long)" FROM "libgtk-x11-2.0.so.0" TYPE char*
IMPORT "gtk_entry_set_text(long,char*)" FROM "libgtk-x11-2.0.so.0" TYPE void
IMPORT "gtk_exit(int)" FROM "libgtk-x11-2.0.so.0" TYPE void
IMPORT "gtk_init(int*,void*)" FROM "libgtk-x11-2.0.so.0" TYPE void
IMPORT "gtk_main" FROM "libgtk-x11-2.0.so.0" TYPE void

' Define the GUI. The below looks ugly, but it is done like this for
' sake of clarity. A better approach could be creating equal length
' string chunks and read them into one variable using READ/DATA.
CONST Calc_Gui$ = "<?xml version=\"1.0\"?> \
<glade-interface> \
  <!-- interface-requires gtk+ 2.6 --> \
  <!-- interface-naming-policy toplevel-contextual --> \
  <widget class=\"GtkWindow\" id=\"window\"> \
    <property name=\"width_request\">250</property> \
    <property name=\"height_request\">225</property> \
    <property name=\"visible\">True</property> \
    <property name=\"title\" translatable=\"yes\">BaCon Calculator</property> \
    <property name=\"resizable\">False</property> \
    <property name=\"window_position\">center</property> \
    <property name=\"default_width\">264</property> \
    <property name=\"default_height\">248</property> \
    <property name=\"icon_name\">calc</property> \
    <signal name=\"delete_event\" handler=\"Calc_Exit\"/> \
    <child> \
      <widget class=\"GtkTable\" id=\"table1\"> \
        <property name=\"visible\">True</property> \
        <property name=\"n_rows\">5</property> \
        <property name=\"n_columns\">5</property> \
        <property name=\"homogeneous\">True</property> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonMemadd\"> \
            <property name=\"label\" translatable=\"yes\">M+</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Memadd\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">3</property> \
            <property name=\"right_attach\">4</property> \
            <property name=\"top_attach\">4</property> \
            <property name=\"bottom_attach\">5</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkEntry\" id=\"entry\"> \
            <property name=\"visible\">True</property> \
            <property name=\"sensitive\">False</property> \
            <property name=\"editable\">False</property> \
            <property name=\"xalign\">1</property> \
          </widget> \
          <packing> \
            <property name=\"right_attach\">5</property> \
            <property name=\"x_padding\">4</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button1\"> \
            <property name=\"label\" translatable=\"yes\">1</property> \
            <property name=\"width_request\">0</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"top_attach\">1</property> \
            <property name=\"bottom_attach\">2</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button3\"> \
            <property name=\"label\" translatable=\"yes\">3</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">2</property> \
            <property name=\"right_attach\">3</property> \
            <property name=\"top_attach\">1</property> \
            <property name=\"bottom_attach\">2</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonC\"> \
            <property name=\"label\" translatable=\"yes\">C</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_C\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">3</property> \
            <property name=\"right_attach\">4</property> \
            <property name=\"top_attach\">1</property> \
            <property name=\"bottom_attach\">2</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonCE\"> \
            <property name=\"label\" translatable=\"yes\">CE</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_CE\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">4</property> \
            <property name=\"right_attach\">5</property> \
            <property name=\"top_attach\">1</property> \
            <property name=\"bottom_attach\">2</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button4\"> \
            <property name=\"label\" translatable=\"yes\">4</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"top_attach\">2</property> \
            <property name=\"bottom_attach\">3</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button5\"> \
            <property name=\"label\" translatable=\"yes\">5</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">1</property> \
            <property name=\"right_attach\">2</property> \
            <property name=\"top_attach\">2</property> \
            <property name=\"bottom_attach\">3</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button6\"> \
            <property name=\"label\" translatable=\"yes\">6</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">2</property> \
            <property name=\"right_attach\">3</property> \
            <property name=\"top_attach\">2</property> \
            <property name=\"bottom_attach\">3</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonAdd\"> \
            <property name=\"label\" translatable=\"yes\">+</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Add\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">3</property> \
            <property name=\"right_attach\">4</property> \
            <property name=\"top_attach\">2</property> \
            <property name=\"bottom_attach\">3</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonMinus\"> \
            <property name=\"label\" translatable=\"yes\">-</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Substract\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">4</property> \
            <property name=\"right_attach\">5</property> \
            <property name=\"top_attach\">2</property> \
            <property name=\"bottom_attach\">3</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button7\"> \
            <property name=\"label\" translatable=\"yes\">7</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"top_attach\">3</property> \
            <property name=\"bottom_attach\">4</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button8\"> \
            <property name=\"label\" translatable=\"yes\">8</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">1</property> \
            <property name=\"right_attach\">2</property> \
            <property name=\"top_attach\">3</property> \
            <property name=\"bottom_attach\">4</property> \
            <property name=\"x_padding\">5</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button9\"> \
            <property name=\"label\" translatable=\"yes\">9</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">2</property> \
            <property name=\"right_attach\">3</property> \
            <property name=\"top_attach\">3</property> \
            <property name=\"bottom_attach\">4</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonMul\"> \
            <property name=\"label\" translatable=\"yes\">*</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Multiply\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">3</property> \
            <property name=\"right_attach\">4</property> \
            <property name=\"top_attach\">3</property> \
            <property name=\"bottom_attach\">4</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonDiv\"> \
            <property name=\"label\" translatable=\"yes\">/</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Divide\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">4</property> \
            <property name=\"right_attach\">5</property> \
            <property name=\"top_attach\">3</property> \
            <property name=\"bottom_attach\">4</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button0\"> \
            <property name=\"label\" translatable=\"yes\">0</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"top_attach\">4</property> \
            <property name=\"bottom_attach\">5</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonMemread\"> \
            <property name=\"label\" translatable=\"yes\">MR</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Memread\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">4</property> \
            <property name=\"right_attach\">5</property> \
            <property name=\"top_attach\">4</property> \
            <property name=\"bottom_attach\">5</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"buttonEq\"> \
            <property name=\"label\" translatable=\"yes\">=</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Equals\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">1</property> \
            <property name=\"right_attach\">3</property> \
            <property name=\"top_attach\">4</property> \
            <property name=\"bottom_attach\">5</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
        <child> \
          <widget class=\"GtkButton\" id=\"button2\"> \
            <property name=\"label\" translatable=\"yes\">2</property> \
            <property name=\"visible\">True</property> \
            <property name=\"can_focus\">False</property> \
            <property name=\"receives_default\">False</property> \
            <signal name=\"clicked\" handler=\"Button_Clicked\" object=\"entry\"/> \
          </widget> \
          <packing> \
            <property name=\"left_attach\">1</property> \
            <property name=\"right_attach\">2</property> \
            <property name=\"top_attach\">1</property> \
            <property name=\"bottom_attach\">2</property> \
            <property name=\"x_padding\">4</property> \
            <property name=\"y_padding\">8</property> \
          </packing> \
        </child> \
      </widget> \
    </child> \
  </widget> \
</glade-interface>"

' Initialize calculator state
calculator_state = 0

' Initialize calculator cache
calculator_cache = 0

' Initialize last calculator action
calculator_action = 0

' Initialize MEM function
mem = 0

' Process the action
SUB Handle_Operator(NUMBER entry)

    LOCAL value

    IF calculator_state = 0 THEN

        SELECT calculator_action
            CASE 1
                value = VAL(gtk_entry_get_text(entry))
                calculator_cache = calculator_cache + value
                gtk_entry_set_text(entry, STR$(calculator_cache))
            CASE 2
                value = VAL(gtk_entry_get_text(entry))
                calculator_cache = calculator_cache - value
                gtk_entry_set_text(entry, STR$(calculator_cache))
            CASE 3
                value = VAL(gtk_entry_get_text(entry))
                calculator_cache = calculator_cache * value
                gtk_entry_set_text(entry, STR$(calculator_cache))
            CASE 4
                value = VAL(gtk_entry_get_text(entry))
                IF value = 0 THEN
                    gtk_entry_set_text(entry, "ERROR")
                ELSE
                    calculator_cache = calculator_cache / value
                    gtk_entry_set_text(entry, STR$(calculator_cache))
                END IF
        END SELECT
    END IF

END SUB

SUB Calc_Exit

    gtk_exit(0)

END SUB

' All button actions here
SUB Button_Memread(NUMBER entry, NUMBER widget)

    calculator_state = 0
    calculator_cache = VAL(gtk_entry_get_text(entry))
    gtk_entry_set_text(entry, STR$(mem))

END SUB

SUB Button_Memadd(NUMBER entry, NUMBER widget)

    mem = VAL(gtk_entry_get_text(entry))

END SUB

SUB Button_C(NUMBER entry, NUMBER widget)

    gtk_entry_set_text(entry, "0")

END SUB

SUB Button_CE(NUMBER entry, NUMBER widget)

    calculator_state = 0
    calculator_action = 0
    calculator_cache = 0
    mem = 0
    gtk_entry_set_text(entry, "0")

END SUB

SUB Button_Add(NUMBER entry, NUMBER widget)

    Handle_Operator(entry)
    calculator_action = 1
    calculator_state = calculator_state + 1

END SUB

SUB Button_Substract(NUMBER entry, NUMBER widget)

    Handle_Operator(entry)
    calculator_action = 2
    calculator_state = calculator_state + 1

END SUB

SUB Button_Multiply(NUMBER entry, NUMBER widget)

    Handle_Operator(entry)
    calculator_action = 3
    calculator_state = calculator_state + 1

END SUB

SUB Button_Divide(NUMBER entry, NUMBER widget)

    Handle_Operator(entry)
    calculator_action = 4
    calculator_state = calculator_state + 1

END SUB

SUB Button_Equals(NUMBER entry, NUMBER widget)

    Handle_Operator(entry)
    calculator_action = 0
    calculator_state = calculator_state + 1

END SUB

SUB Button_Clicked(NUMBER entry, NUMBER widget)

    LOCAL button$, text$

    button$ = gtk_button_get_label(widget)

    text$ = gtk_entry_get_text(entry)

    IF EQUAL(text$, "0") OR calculator_state > 0 THEN
        calculator_cache = VAL(text$)
        gtk_entry_set_text(entry, button$)
    ELSE
        gtk_entry_set_text(entry, CONCAT$(text$, button$))
    ENDIF

    calculator_state = 0

END SUB

' Main program
gtk_init(0, 0)

xml = glade_xml_new_from_buffer(Calc_Gui$, LEN(Calc_Gui$), 0, 0)

glade_xml_signal_autoconnect(xml)

gtk_main