# $Id: s.WebAgent.xotcl 1.8 01/03/23 21:55:31+01:00 neumann@somewhere.wu-wien.ac.at $
package provide xotcl::awo::webAgent 0.8

package require xotcl::mos::agent
package require xotcl::trace
package require xotcl::pattern::onCalleeProxy
package require xotcl::mos::invoker
package require xotcl::mixinStrategy

#
Class WebFacade -superclass WebObject -parameter {{webagent ""}}

#
# per default the web facade is exported (with not exported procs)
#
WebFacade instproc init args {
  next
  [self] mixinStrategy Send=TypedString
  [[self] place] exportObjs [self]
}

#
# conviniece method that lets us export the procs currently
# exported by the shielded web agent
#
WebFacade instproc exportProcsOfWebAgent {} {
  foreach p [[[self] webagent] exportedProcs] {
    [self] exportProcs $p
  }
}
#
# bidrectional attaching -> same method exists for webAgents (attachWebFacade)
# only one of them has to be called
#
WebFacade instproc attachWebAgent webAgent {
  $webAgent webfacade [self]
  [self] webagent $webAgent
}

WebFacade abstract instproc listExportedProcs args
WebFacade abstract instproc simplePage args

Class WebFacadeHtml -superclass WebFacade

WebFacadeHtml instproc init args {
  [self] contentType text/html
  next
}

WebFacadeHtml instproc listExportedProcs args {
  [self] instvar {webagent n}
  #
  # place must be a Html place!
  #
  set place [HtmlPlace getInstance]
  set c "
  The following options are avaiable on $n:
  "

  foreach i [$n exportedProcs] {
    set href [[self] selfAction "$n $i"]
    set app {
      <p> <a href= "$href">$i</a>
    }
    append c [subst -nobackslashes $app]
  }
  return [[self] simplePage $place $n $c]
}

WebFacadeHtml instproc simplePage {title heading content {closing ""}}  {
  set place [Place getInstance]
  set c {
    <html>
    <head>
    <title>$title</title>
    </head>
    <body>
    <h1> $heading </h1>
    <hr>
    <p> 
    
    $content
    
    <p> $closing

    <p><hr><p>
    </body>
    </html>
  }
  return [subst -nobackslashes -nocommands $c] 
}

#
# builds a simple Form -- args are tupels of the form
# {text, name, type, default, size}
#
#
WebFacadeHtml instproc simpleForm {action args} {
  set action [[self] selfAction $action]
  set c {
    <form method="get" action="$action">
    <TABLE>
  }
  foreach {text name type def size} $args {
    append c "
      <TR>
        <TD>$text: </TD>
        <TD><input name=\"$name\" type=\"$type\" size=\"$size\" value=\"$def\"></TD>
      </TR>
    "
  }
  append c {
    <TR>
      <td><input type=submit value="Submit"></td>
      <td><input type=reset value="Reset"></td>
    </TR>
    </TABLE>

    </FORM>
  }
  return [subst -nobackslashes -nocommands $c]
}

#
# Web Agent are special agents that allow us to define another
# object in the paramter webfacade as a facade for the web agent
# itself and the sub-system shielded by the web agent with an interface
# for agents
#
Class WebAgent -superclass Agent -parameter {
  {webfacade ""}
}

WebAgent instproc init args {
  [self] exportProcs invokeFacade
  next
}

#
# attach an object of type webFacade to this web agent
#
WebAgent instproc attachWebFacade webFacade {
  $webFacade webagent [self]
  [self] webfacade $webFacade
} {
  [$webFacade istype WebFacade]
} {} 

#
# let the web agents facade handle the call -> interprete args
# as "method args"
# return result of the invoker
#
WebAgent instproc invokeFacade {args} {
  set a ""
  set m ""
  set l [llength $args]
  set o [[self] webfacade]
  if {$l > 0} {
    set m [lindex $args 0]
  }
  if {$l > 1} {
    set a [lrange $args 1 end]
  } 
    
  #puts stderr "Web Agent [self]->invoke:  OBJ: $o PROC: $m ARGS: $a"

  #
  # tell the invoker to redirect the call to the webfacade object
  #
  set re [RedirectException [self]::[[self] autoname re] \
	    -obj $o -method $m -arguments $a]

  return $re
}
    

WebAgent instproc default args {
  return [next]
}
