###############################################################################
#
# winforms5.eagle --
#
# Extensible Adaptable Generalized Logic Engine (Eagle)
#
# Copyright (c) 2007-2012 by Joe Mistachkin.  All rights reserved.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: $
#
###############################################################################

source [file join [file normalize [file dirname [info script]]] prologue.eagle]

###############################################################################
# MONO: On Mono 3.0.2 beta, these tests do not function properly due to
#       a total failure to load the System.Windows.Forms assembly, resulting
#       from incorrect DLL mappings in the "etc/mono/config" configuration
#       file copied by the installer.  Attempts to load and/or use Windows
#       Forms functionality will result in a very complex looking exception,
#       with the innermost exception being very similar to the following:
#
#       System.DllNotFoundException: /tmp/install/lib/libgdiplus.so
#
#       The workaround to "fix" this issue on Windows is to simply remove
#       the both "gdiplus" related lines from the configuration file.
#
#       See: https://bugzilla.xamarin.com/show_bug.cgi?id=8309
###############################################################################
# MONO: Due to a Mono bug, some tests are disabled on Mono.
#       See: https://bugzilla.novell.com/show_bug.cgi?id=471257
###############################################################################

runTest {test winForms-5.1 {create and show a form with proc event} -setup {
  proc handleClickEvent { sender e } {
    #
    # NOTE: We know this is a MouseEventArgs because this is a
    #       click event handler.
    #
    lappend ::x [$sender ToString] [$e X] [$e Y] [$e Button]

    #
    # NOTE: Terminate our wait.
    #
    set ::forever 1
  }

  set savedSleeptime [interp sleeptime {}]; # save
} -body {
  set assembly [object load -import System.Windows.Forms]
  set form [object create -alias Form]

  $form Text [appendArgs [info engine] " Test Form Title"]
  $form Show

  set button [object create -alias System.Windows.Forms.Button]

  $button Left [expr {([$form ClientSize.Width] - [$button Width]) / 2}]
  $button Top [expr {([$form ClientSize.Height] - [$button Height]) / 2}]

  $button Text "Click Here"
  $button add_Click handleClickEvent

  object invoke $form.Controls Add $button

  interp sleeptime {} 200

  set x [list]
  set mouseEventArgs [object create -alias MouseEventArgs Left 1 12 34 0]
  after 1000 [list $button -flags +NonPublic OnClick $mouseEventArgs]

  vwait forever

  set x
} -cleanup {
  cleanupWinForms

  interp sleeptime {} $savedSleeptime; # restore

  unset -nocomplain x forever mouseEventArgs button form assembly \
      savedSleeptime

  catch {object removecallback handleClickEvent}

  rename handleClickEvent ""
} -constraints {eagle compile.WINFORMS winForms} -result \
{{System.Windows.Forms.Button, Text: Click Here} 12 34 Left}}

###############################################################################

runTest {test winForms-5.2 {create/show threaded cancel form} -setup {
  proc threadStart { args } {
    #
    # NOTE: Load the WinForms assembly.
    #
    set assembly [object load -import System.Windows.Forms]

    #
    # NOTE: Create a new, empty, form.
    #
    set form [object create -alias Form]

    #
    # NOTE: Set the caption of the form and make the form is visible on the
    #       screen.
    #
    $form Text [appendArgs [info engine] " Test Form Title"]
    $form Show

    #
    # NOTE: Create a button and position it at the center of the form.  At
    #       this point, the button will not actually be on the form; however,
    #       when it is placed there (below), the position will be correct.
    #
    set button [object create -alias System.Windows.Forms.Button]

    $button Left [expr {([$form ClientSize.Width] - [$button Width]) / 2}]
    $button Top [expr {([$form ClientSize.Height] - [$button Height]) / 2}]

    #
    # NOTE: Set the caption of the button and add a click event handler.
    #
    $button Text "Cancel"
    $button add_Click handleClickEvent

    #
    # NOTE: Physically add the button to the form.
    #
    object invoke $form.Controls Add $button

    #
    # NOTE: Set the maximum number of milliseconds to sleep while checking for
    #       events.
    #
    interp sleeptime {} 200

    #
    # NOTE: In about 1 second, simulate the button being clicked by the mouse.
    #
    set ::x [list]
    set mouseEventArgs [object create -alias MouseEventArgs Left 1 12 34 0]
    after 1000 [list $button -flags +NonPublic OnClick $mouseEventArgs]

    #
    # NOTE: Wait until the main thread signals us to quit.
    #
    vwait ::forever
  }

  proc handleClickEvent { sender e } {
    #
    # NOTE: We know this is a MouseEventArgs because this is a
    #       click event handler.
    #
    lappend ::x [$sender ToString] [$e X] [$e Y] [$e Button]

    #
    # NOTE: Cancel the entire script in progress in about 2 seconds.  This will
    #       cause the main thread to return from the test body and start the
    #       cleanup block.  Normally, this would be fatal to the test suite
    #       itself; however, this test uses the "-noCancel" flag to prevent
    #       unwinding the interpreter stack beyond the script being tested.
    #
    after 2000 [list interp cancel -unwind]

    #
    # NOTE: Process events now.  This wait will return in about 2 seconds when
    #       the script in progress is canceled.
    #
    vwait ::forever
  }

  set savedSleeptime [interp sleeptime {}]; # save
  object import System.Threading
} -body {
  set t [object create -alias Thread threadStart]

  $t Start; while {1} {}; # thread is still running...
} -cleanup {
  cleanupWinForms
  object unimport -importpattern System.Threading

  #
  # NOTE: Signal the other thread to quit and then wait for it; however,
  #       depending on various timing considerations, the other thread may
  #       already be dead.  In that case, this code should be harmless.
  #
  set forever 1
  if {[info exists t]} then {catch {$t Join}}

  interp sleeptime {} $savedSleeptime; # restore

  unset -nocomplain t x forever savedSleeptime

  catch {object removecallback handleClickEvent}
  catch {object removecallback threadStart}

  rename handleClickEvent ""
  rename threadStart ""
} -constraints {eagle tip285 compile.WINFORMS winForms compile.THREADING} \
-noCancel true -returnCodes 1 -result {eval unwound}}

###############################################################################

source [file join [file normalize [file dirname [info script]]] epilogue.eagle]
