# HtmlBackend.py
# 
# Copyright (c) 1999-2001 Philip Hunt
# parts Copyright (c) 2001 Ludger Humbert
# Released under the GNU General Public Licence
# 
# HTML backend for Parrot
# This is a demonstration backend; it was written to verify that
# the basic design of the Parrot backend system is reasonably 
# sensible, and to serve as an example for people wishing to
# write their own backends. It doesn't do anything particularly
# useful in itself.

# Last altered: 14-Jun-2001
# History:
# 7-Aug-1999 PhilHunt: created
# 24-Aug-1999: added getAttrDoc()
# 12-Feb-2000: added Html_textArea class
# 1-Jun-2001 LH: mods for radio buttons

from inrep import *

from backend import *

#===========================================================
#####  HTML backend  ####################################### 
#===========================================================

class Html_GLOBAL(Backend_GLOBAL):

   def getStartCode(self):
      return """<html>
<!-- autogenerated by Parrot's HtmlBackend module -->
<head>
<title>An HTML Form</title>
</head>
<body bgcolor="#cccccc" fgcolor="#000000" text="#000000">

<p>Autogenerated by Parrot's HtmlBackend module
<form>
""" 

   def getCodeBetweenComponents(self): return '\n' 


   def getEndCode(self):
      return """
</form>
</body></html>
"""

   def getBackendSignature(self): return 'Html'

   def produceCode(self):
      return self.getCode()

   # The Html backend produces files with an .html extension
   def fileExtension(self): return '.html'

   # return list of container types understood by this backend:
   def getContainerTypes(self):
      return ('window', 'colLayout', 'rowLayout', 'table', 'tr', 'td',
         'menuBar', 'menu')

   # return list of components which aren't containers
   def getNonContainerTypes(self):
      return ('menuItem', 'button', 'label', 'textField', 'checkBox',
         'radioButton')

#===========================================================
# containers
#===========================================================

#class Html_container(Backend_container): pass

class Html_window(Backend_container):

   def getAttrDoc(self):
      return {'id': 'the identifier of the HTML form',
         'text': 'the window title'}

   def getStartCode(self): 
      return """ 
<table border=0 cellspacing=0 cellpadding=1 bgcolor='#333333' width='99%%'>
<tr><td align=center>
<font color="#ffffff"><b>%s</b></font>
</td></tr>
</table>
""" %(self.getText())

   def getCodeBetweenComponents(self): return '' 

   def getEndCode(self): return '\n<p>\n<hr noshade>\n' 

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_colLayout(Backend_container):
   def getAttrDoc(self):
      return {'text': "the colLayout's border name (to do)"}

   def getStartCode(self): return '' 
   def getCodeBetweenComponents(self): return '\n<br>' 
   def getEndCode(self): return '\n' 

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_rowLayout(Backend_container):
   def getAttrDoc(self):
      return {'text': "the rowLayout's border name (to do)"}

   def getStartCode(self): 
      details = ''
      details = details + ' border="1" bgcolor="#ffbbbb"'
      return '<p><table' + details + '>\n<tr><td align="left" valign="top">\n' 

   def getCodeBetweenComponents(self): 
      return '</td>\n<td align="left" valign="top">\n<p>' 

   def getEndCode(self): 
      return '</td></tr></table>\n' 


#===========================================================
# table containers
#===========================================================

class Html_table(Backend_container):
   def getAttrDoc(self):
      return {'text': 'the table title (to do)'}

   def getStartCode(self): 
      return '<table bgcolor="#ddffee">' 
   def getCodeBetweenComponents(self): 
      return '\n' 
   def getEndCode(self): 
      return '</table>\n' 

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_tr(Backend_container):
   def getAttrDoc(self):
      return { }

   def getStartCode(self): 
      return '<tr>' 
   def getCodeBetweenComponents(self): 
      return '\n' 
   def getEndCode(self): 
      return '</tr>\n' 

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_td(Backend_container):
   def getAttrDoc(self):
      return {'rowspan': 
         'number of rows spanned by this table element (to do)',
         'colspan': 
         'number of columns spanned by this table element (to do)'}

   def getStartCode(self): 
      return '<td align="left" valign="top">' 
   def getCodeBetweenComponents(self): 
      return '\n<br />' 
   def getEndCode(self): 
      return '</tr>\n' 


#===========================================================
# menu classes
#===========================================================

class Html_menuBar(Backend_container):

   def getAttrDoc(self):
      return { }

   def getCode(self):
      #>>>>> 1st, get extent of menus, into numMenus, and maxMenuItems

      # this assumes that all subcomponents are menus; if they
      # are not, the result is undefined, but probably bad.
      # (At the moment no checking is done to ensure sub-components
      # are of a correct type; probably it should be.)
      numMenus = len(self.components)

      maxMenuItems = 0
      for sc in self.components:
         mi = sc.getNumItems()
         if mi > maxMenuItems: maxMenuItems = mi

      result = '<table border="2" cellspacing="2" bgcolor="#66ff66">\n'
      for y in xrange(-1, maxMenuItems):
         result = result + '  <tr>'
         for x in xrange(0, numMenus):
            #print 'x=',x
            inMenuBar = ( y == -1)
            if inMenuBar:
               result = result + '<th bgcolor="#ccccff">' \
                  + self.components[x].getText() + '</th>'
            else:
               if y < self.components[x].getNumItems():
                  td = self.components[x].components[y].getText()
               else:
                  td = ''
               result = result + '<td bgcolor="#f0d0cc">' + td + '</td>'
         #//for x
         result = result + '</tr>\n'
      #//for y
      result = result + '</table>\n<hr noshade>\n'
      return result


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_menu(Backend_container): 

   def getAttrDoc(self):
      return {'text': 'the menu title'}

   # code generation for menus is handled by Html_menuBar,
   # so we don't need to do it here:
   def getCode(self): return ''

   def getNumItems(self):
      return len(self.components)      

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_menuItem(Backend_component):
   def getAttrDoc(self):
      return {'text': 'the text in the menu item'}

   # code generation for menus is handled by Html_menuBar,
   # so we don't need to do it here:
   def getCode(self): return ''


#===========================================================
# non-container components
#===========================================================

#class Html_component(Backend_component): pass

class Html_button(Backend_component):
   def getAttrDoc(self):
      return {'id': 'the identifier of the HTML button',
         'text': "the button's text"}

   def getCode(self):
      return '<input type=button name="%s" value="%s"> ' % (
         self.getId(),
         self.getText()) 


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_label(Backend_component):
   def getAttrDoc(self):
      return {'text': "the label's text"}

   def getCode(self):
      return self.getText() 
      
   def getLabel(self):      
      return self.getText()

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_textField(Backend_component):
   def getAttrDoc(self):
      return {'id': 'the identifier of the HTML text field',
         'text': 'text that goes in the textfield at startup',
         'cols': 'number of columns in textfield'}

   def getCode(self):
      cols = ''
      if self.attr.has_key('cols'):
         cols = ' size="%s"' % self.attr['cols'] 
      return '<input type=text name="%s"%s value="%s">' % (
         self.getId(),
         cols,
         self.getText())
        
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_textArea(Backend_component):
   def getAttrDoc(self):
      return {'id': 'the identifier of the HTML text field',
         'text': 'text that goes in the textfield at startup',
         'xsize': 'number of columns in textarea',
         'ysize': 'number of rows in the textarea'}

   def getCode(self):
      rows = ''
      if self.attr.has_key('ysize'):
         rows = ' rows="%s"' % self.attr['ysize'] 
      cols = ''
      if self.attr.has_key('xsize'):
         cols = ' cols="%s"' % self.attr['xsize'] 
      return '<textarea name="%s"%s%s>\n%s\n</textarea>' % (
         self.getId(),
         rows, cols,
         self.getText())
        

#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_checkBox(Backend_component):
   def getAttrDoc(self):
      return {'id': 'the identifier of the HTML checkbox',
         'text': "the checkbox's text"}

   def getCode(self):
      return '<input type=checkbox name="%s"> %s' % (
         self.getId(),
         self.getText())

  
#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

class Html_radioButton(Backend_component):
   def getAttrDoc(self):
      return {'group': 'the identifier for the group of '
                     + 'radio buttons which this one belongs to',
         'id': 'the identifier of the HTML radio button',
         'text': "the radio button's text"}

   def getCode(self):
#      return '<input type=radio name="%s"> %s' % (
      return '<input type=radio name="%s" value="%s"> %s' % (
         self.getAttr("group"),
         self.getId(),
         self.getText())

  

#===========================================================

#end 




