//<script language="jscript">

import System

// Gdy pojawią się błedy kompilacj usuń linie poniżej
@set @interface_bugs = true

package FormBuilder
{
  enum AlignmentType
  {
    None = 1,
    Top = 2,
    Left = 4,
    Bottom = 8,
    Right = 16,
    Middle = 32,
    Centre = 64,

    TopLeft = Top | Left,
    BottomRight = Bottom | Right,
    MiddleCentre = Middle | Centre,

    HorizontalMask = Left | Right | Centre,
    VerticalMask = Top | Bottom | Middle
  }

  enum StretchType
  {
    None = 0,
    Vertical = 1,
    Horizontal = 2,
    All = 3
  }

  interface IGenerateSource
  {
    function get Identifier() : String
    function get TypeName() : String
      
    function Declaration(prefix : String) : String
    function Initialisation(prefix : String) : String
    function SupportingCode(prefix : String) : String
  }

  interface IRectangle
  {
    function get Top() : int
    function set Top(val : int)
      
    function get Left() : int
    function set Left(val : int)
      
    function get Width() : int
    function set Width(val : int)
    
    function get Height() : int
    function set Height(val : int)

    function get DefaultWidth() : int
    function get DefaultHeight() : int
      
    function get Stretch() : StretchType
    function get Alignment() : AlignmentType
  }

  class GenericRectangle implements IRectangle
  {
    protected var alignment : AlignmentType = AlignmentType.None
    protected var stretch : StretchType = StretchType.None

    protected var top : int = 0
    protected var left : int = 0
    protected var height : int = 0
    protected var width : int = 0

    function get DefaultWidth() : int { return 0 }
    function get DefaultHeight() : int { return 0 }

    function GenericRectangle(width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      this.width = width
      this.height = height
      this.stretch = stretch
      this.alignment = alignment

      if (this.width == 0)
        this.width = DefaultWidth

      if (this.height == 0)
        this.height = DefaultHeight
        
      if ((alignment & AlignmentType.HorizontalMask) == 0)
        this.alignment |= AlignmentType.Left

      if ((alignment & AlignmentType.VerticalMask) == 0)
        this.alignment |= AlignmentType.Top
    }

    function GenericRectangle(width : int, height : int)
    {
      this(width, height, 0, 0)
    }

    function get Top() : int { return top }
    function set Top(val : int) { top = val }

    function get Left() : int { return left }
    function set Left(val : int) { left = val }
      
    function get Width() : int { return width }
    function set Width(val : int) { width = val }

    function get Height() : int { return height }
    function set Height(val : int) { height = val }

    function get Stretch() : StretchType { return stretch }
    function get Alignment() : AlignmentType { return alignment }

    function ToString() : String
    {
      return "My Position: (" + left + ", " + top + "). My Size: (" + Width + ", " + Height + ")\r\n"
    }
  }

  interface IGroup implements IRectangle
  {
    function get Padding() : int
      
    function Add(child : IRectangle, data : Object)
    function get Children() : IRectangle[]
    function get ChildCount() : int

    function LayoutChildren(actualWidth : int, actualHeight : int)

@if (@interface_bugs != true)
    function LayoutChildren()
@end
  }

  class GenericLayout extends GenericRectangle implements IGroup
  {
    const MAX_CHILDREN : int = 16

    protected var children : IRectangle[] = new IRectangle[MAX_CHILDREN]
    protected var childCount : int = 0
    protected var padding : int = 8

    protected var layoutWidth : int = 0
    protected var layoutHeight : int = 0

  @if (@interface_bugs)
    function GetChild(i : int) : Object { return children[i] }
  @end

    function GenericLayout(alignment : AlignmentType, padding : int)
    {
      // A layout is only stretchable if a child is added that is stretchable
      super(0, 0, StretchType.None, alignment)
      this.padding = padding
    }
      
    function get Width() : int { return layoutWidth ? layoutWidth : width }
    function set Width(val : int) { layoutWidth = val }

    function get Height() : int { return layoutHeight ? layoutHeight : height }
    function set Height(val : int) { layoutHeight = val }

    function get Padding() : int { return padding }
      
    function get Children() : IRectangle[]
    {
      return children
    }

    function get ChildCount() : int { return childCount }

    protected function adjustWidth(child : IRectangle)
    {
      width += child.Width
      if (childCount > 0)
        width += padding
    }    

    protected function adjustHeight(child : IRectangle)
    {
      height += child.Height
      if (childCount > 0)
        height += padding
    }    

    function Add(child : IRectangle, data : Object)
    {
      if (childCount == MAX_CHILDREN)
        throw "Too many children"

      // Derived classes override these
      adjustWidth(child)
      adjustHeight(child)
        
      // Adjust stretch, if necessary
      stretch |= child.Stretch
        
      children[childCount++] = child
    }

    protected function layoutHorizontally()
    {
      var child : IRectangle
      var i : int
      var pos : int = 0
      var alreadyStretched : boolean = false
        
      for (i = 0; i < childCount; i++)
      {
        child = children[i]
        child.Left = pos
        
        // Only allows for 1 stretchable thing!
        if ((child.Stretch & StretchType.Horizontal) && alreadyStretched == false)
        {
          child.Width += layoutWidth - width
          alreadyStretched = true
        }
          
        pos += child.Width + padding
      }
    }

    protected function layoutVertically()
    {
      var child : IRectangle
      var i : int
      var pos : int = 0
      var alreadyStretched : boolean
        
      for (i = 0; i < childCount; i++)
      {
        child = children[i]
        child.Top = pos
        
        // Only allows for 1 stretchable thing!
        if ((child.Stretch & StretchType.Vertical) && alreadyStretched == false)
        {
          child.Height += layoutHeight - height
          alreadyStretched = true
        }

        pos += child.Height + padding
      }
    }
    
    protected function layoutChildGroups()
    {
      var child : IRectangle
      var group : IGroup

      for (var i : int = 0; i < childCount; i++)
      {
        child = children[i]
        if (child instanceof IGroup)
        {
          group = IGroup(child)
          
          var stretch : StretchType = group.Stretch
          if (stretch == StretchType.None)
            group.LayoutChildren()
          else if (stretch == StretchType.Horizontal)
            group.LayoutChildren(width, child.Height)
          else if (stretch == StretchType.Vertical)
            group.LayoutChildren(child.Width, height)
          else
            group.LayoutChildren(width, height)
        }
      }
    }
      
    function LayoutChildren(actualWidth : int, actualHeight : int)
    {
      var child : IRectangle
      var group : IGroup

      if (actualWidth == 0)
        actualWidth = width
      if (actualHeight == 0)
        actualHeight = height

      layoutWidth = actualWidth
      layoutHeight = actualHeight
      
      // Special case for a single child that stretches
      if (childCount == 1 && children[0].Stretch != StretchType.None)
      {
        child = children[0]
        child.Top = child.Left = 0
        child.Height = layoutHeight
        child.Width = layoutWidth
          
        // Ask it to layout children, if required
        if (child instanceof IGroup)
          IGroup(child).LayoutChildren()
            
        return
      }
      
      layoutVertically()
      layoutHorizontally()
      layoutChildGroups()
    }

    function LayoutChildren()
    {
      LayoutChildren(width, height)
    }

    function ToString() : String
    {
      var text : String
      var i : int
        
      text = super.ToString()
        
      for (i = 0; i < childCount; i++)
  @if (@interface_bugs)
        text += "  " + Object(children[i]).ToString()
  @else
        text += "  " + children[i] // .ToString()
  @end
          
      return text
    }
  }
  
  class PaddedLayout extends GenericLayout
  {

    function PaddedLayout(alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
    }

    function Add(child : IRectangle, data : Object)
    {
      // Only one child allowed
      if (childCount >= 1)
        throw "Too many children"

      width = child.Width + 2 * padding
      height = child.Height + 2 * padding
      stretch |= child.Stretch

      children[0] = child
      childCount ++
    }

    function LayoutChildren(actualWidth : int, actualHeight : int)
    {
      var child : IRectangle
      var group : IGroup
      
      // Nothing to do
      if (childCount != 1)
        return

      if (actualWidth == 0)
        actualWidth = width
      if (actualHeight == 0)
        actualHeight = height

      layoutWidth = actualWidth
      layoutHeight = actualHeight
        
  @if (@interface_bugs)
      child = IRectangle(GetChild(0))
  @else
      child = children[0]
  @end
      
      switch (child.Alignment & AlignmentType.HorizontalMask)
      {
      case AlignmentType.Left:
        child.Left = padding
        break
      case AlignmentType.Right:
        if (child.Stretch & StretchType.Horizontal)
          child.Left = padding
        else
          child.Left = layoutWidth - child.Width - padding
        break
      case AlignmentType.Centre:
        child.Left = (layoutWidth - child.Width) / 2
        break
      }
      
      switch (child.Alignment & AlignmentType.VerticalMask)
      {
      case AlignmentType.Top:
        child.Top = padding
        break
      case AlignmentType.Bottom:
        if (child.Stretch & StretchType.Vertical)
          child.Top = padding
        else
          child.Top = layoutHeight - child.Height - padding
        break
      case AlignmentType.Middle:
        child.Top = (layoutHeight - child.Height) / 2
        break
      }
        
      if (child.Stretch & StretchType.Horizontal)
        child.Width = layoutWidth - 2 * padding
        
      if (child.Stretch & StretchType.Vertical)
        child.Height= layoutHeight - 2 * padding
        
      // Layout the child if it's a group
      layoutChildGroups()
    }
    
    protected function layoutChildGroups()
    {
      var child : IRectangle
      var group : IGroup

  @if (@interface_bugs)
      child = IRectangle(GetChild(0))
  @else
      child = children[0]
  @end

      if (child instanceof IGroup)
      {
        group = IGroup(child)
        
        var stretch : StretchType = group.Stretch
        if (stretch == StretchType.None)
          group.LayoutChildren()
        else if (stretch == StretchType.Horizontal)
          group.LayoutChildren(width - 2 * padding, child.Height)
        else if (stretch == StretchType.Vertical)
          group.LayoutChildren(child.Width, height - 2 * padding)
        else
          group.LayoutChildren(width - 2 * padding, height - 2 * padding)
      }
    }
  }

  class VerticalLayout extends GenericLayout
  {
    function VerticalLayout(alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
    }

    protected function adjustWidth(child : IRectangle)
    {
      if (child.Width > width)
        width = child.Width
    }    

    protected function layoutHorizontally()
    {
      var child : IRectangle
      var i : int
        
      for (i = 0; i < childCount; i++)
      {
  @if (@interface_bugs)
        child = IRectangle(GetChild(i))
  @else
        child = children[i]
  @end
        switch (child.Alignment & AlignmentType.HorizontalMask)
        {
        case AlignmentType.Left:
          child.Left = 0
          break
        case AlignmentType.Right:
          if (child.Stretch & StretchType.Horizontal)
            child.Left = 0
          else
            child.Left = layoutWidth - child.Width
          break
        case AlignmentType.Centre:
          child.Left = (layoutWidth - child.Width) / 2
          break
        }
          
        //if ((child.Stretch & StretchType.Horizontal) && !(child instanceof IGroup))
        if (child.Stretch & StretchType.Horizontal)
          child.Width = layoutWidth
      }
    }
  }

  class HorizontalLayout extends GenericLayout
  {

    function HorizontalLayout(alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
    }
      
    protected function adjustHeight(child : IRectangle)
    {
      if (child.Height > height)
        height = child.Height
    }    

    protected function layoutVertically()
    {
      var child : IRectangle
      var i : int
        
      for (i = 0; i < childCount; i++)
      {
  @if (@interface_bugs)
        child = IRectangle(GetChild(i))
  @else
        child = children[i]
  @end
        switch (child.Alignment & AlignmentType.VerticalMask)
        {
        case AlignmentType.Top:
          child.Top = 0
          break
        case AlignmentType.Bottom:
          if (child.Stretch & StretchType.Vertical)
            child.Top = 0
          else
            child.Top = layoutHeight - child.Height
          break
        case AlignmentType.Middle:
          child.Top = (layoutHeight - child.Height) / 2
          break
        }
        if (child.Stretch & StretchType.Vertical)
          child.Height = layoutHeight
      }
    }
  }

  class GenericControl extends GenericRectangle implements IGenerateSource
  {
    protected var identifier : String
    protected var text : String
    protected var typeName : String

    const MAX_EVENTS : int = 16

    protected var events : Event[] = new Event[MAX_EVENTS]
    protected var eventCount : int = 0
      
    function get Identifier() : String { return identifier }
    function get TypeName() : String { return typeName }
    function get Text() : String { return text }

    function get DefaultWidth() : int { return 56 }
    function get DefaultHeight() : int { return 24 }
      
    function GenericControl(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(width, height, stretch, alignment)
      this.identifier = identifier
      this.text = text
    }
      
    function GenericControl(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }
    
    function AddEvent(event : String, sourceCode : String)
    {
      events[eventCount++] = new Event(event, sourceCode)
    }
       
    function Declaration(prefix : String) : String
    {
      return prefix + "private var " + identifier + " : " + typeName + ";\r\n"
    }
      
    function Initialisation(prefix : String) : String
    {
      var text : String
      var event : Event
        
      text  = "\r\n"
      text += prefix + "//\r\n"
      text += prefix + "// " + identifier + "\r\n"
      text += prefix + "//\r\n"
      text += prefix + identifier + " = new " + typeName + ";\r\n"
      text += prefix + identifier + ".Location = new System.Drawing.Point(" + left + ", " + top + ");\r\n"
      text += prefix + identifier + ".Size = new System.Drawing.Size(" + width + ", " + height + ");\r\n"
      text += prefix + identifier + ".Name = \"" + identifier + "\";\r\n"
      text += prefix + identifier + ".Text = \"" + this.text + "\";\r\n"
      text += prefix + identifier + ".Anchor = " + GetAnchorStyles(stretch, alignment) + ";\r\n"
      
      for (var i : int = 0; i < eventCount; i++)
      {
        event = events[i]
        text += prefix + identifier + ".add_" + event.Name + "(" + identifier + "_" + event.Name + ");\r\n"
      }

      return text  
    }
      
    function SupportingCode(prefix : String) : String
    {
      var source = ""
      var event : Event
      
      if (eventCount > 0)
        source  = prefix + "\r\n"
        
      for (var i : int = 0; i < eventCount; i++)
      {
        event = events[i]
        
        source += prefix + "// " + event.Name + " Event handler for " + identifier + "\r\n"
        source += prefix + "function " + identifier + "_" + event.Name + "(o : Object, e : EventArgs)\r\n"
        source += prefix + "{\r\n"
        source += prefix + prefix + event.Source + ";\r\n"
        source += prefix + "}\r\n"
      }
        
      return source
    }
      
    static function GetAnchorStyles(stretch : StretchType, alignment : AlignmentType)
    {
      var anchor : Array = []

      if (stretch & StretchType.Vertical || alignment & AlignmentType.Top)
        anchor.push("AnchorStyles.Top")
      if (stretch & StretchType.Vertical || alignment & AlignmentType.Bottom)
        anchor.push("AnchorStyles.Bottom")
      if (stretch & StretchType.Horizontal || alignment & AlignmentType.Left)
        anchor.push("AnchorStyles.Left")
      if (stretch & StretchType.Horizontal || alignment & AlignmentType.Right)
        anchor.push("AnchorStyles.Right")
          
      if (anchor.length == 0)
        return "AnchorStyles.None"
      else
        return anchor.join(" | ")
    }
    
    class Event
    {
      var Name : String
      var Source : String
      
      function Event(name : String, source : String)
      {
        Name = name
        Source = source
      }
    }
  }

  class Label extends GenericControl
  {
      
    function Label(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.Label"
    }

    function Label(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }

    function get DefaultHeight() : int { return 16 }
  }

  class Button extends GenericControl
  {
      
    function Button(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.Button"
    }

    function Button(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }
  }

  class TextBox extends GenericControl
  {
      
    function TextBox(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.TextBox"
    }

    function TextBox(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }

    function Initialisation(prefix : String) : String
    {
      var text : String = super.Initialisation(prefix)
      text += prefix + "// set Multiline=false to disaable multiple lines in the TextBox\r\n"
      text += prefix + identifier + ".Multiline = true;\r\n"
      text += prefix + "// set ReadOnly=true to disable the TextBox\r\n"
      text += prefix + identifier + ".ReadOnly = false;\r\n"
        
      return text
    }
  }

  class CheckBox extends GenericControl
  {
      
    function CheckBox(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.CheckBox"
    }

    function CheckBox(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }

    function get DefaultHeight() : int { return 16 }
  }

  class ComboBox extends GenericControl
  {
      
    function ComboBox(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.ComboBox"
    }

    function ComboBox(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }
  }

  class ListBox extends GenericControl
  {
      
    function ListBox(identifier : String, text : String, width : int, height : int, stretch : StretchType, alignment : AlignmentType)
    {
      super(identifier, text, width, height, stretch, alignment)
      typeName = "System.Windows.Forms.ListBox"
    }

    function ListBox(identifier : String, text : String, width : int, height : int)
    {
      this(identifier, text, width, height, 0, 0)
    }

    function Initialisation(prefix : String) : String
    {
      var text : String
      var event : Event
        
      text  = "\r\n"
      text += prefix + "//\r\n"
      text += prefix + "// " + identifier + "\r\n"
      text += prefix + "//\r\n"
      text += prefix + identifier + " = new " + typeName + ";\r\n"
      text += prefix + identifier + ".Location = new System.Drawing.Point(" + left + ", " + top + ");\r\n"
      text += prefix + identifier + ".Size = new System.Drawing.Size(" + width + ", " + height + ");\r\n"
      text += prefix + identifier + ".Name = \"" + identifier + "\";\r\n"
      text += prefix + identifier + ".Anchor = " + GetAnchorStyles(stretch, alignment) + ";\r\n"
      text += prefix + identifier + ".ItemHeight = 16;\r\n"
      text += prefix + identifier + ".Items.AddRange([\"Item 1\",\"Item 2\",\"Item 3\"]);\r\n"
      text += prefix + identifier + ".SetSelected(0,true);\r\n"
      return text  
    }
    
  }

  class GenericPanel implements IGenerateSource
  {
    protected var identifier : String
    protected var typeName : String
    protected var owner : IGroup
      
    function get Identifier() : String { return identifier }
    function get TypeName() : String { return typeName }
    function get Text() : String { return "" }
      
    function GenericPanel(identifier : String, owner : IGroup)
    {
      this.identifier = identifier
      this.owner = owner
      typeName = "System.Windows.Forms.Panel"
    }
       
    function Declaration(prefix : String) : String
    {
      var i : int
      var declaration : String = ""
      var child : Object
        
      for (i = 0; i < owner.ChildCount; i++)
      {
        child = owner.Children[i]
          
        if (child instanceof IGenerateSource)
        {
          declaration += IGenerateSource(child).Declaration(prefix)
        }
      }
          
      return declaration + prefix + "private var " + identifier + " : " + typeName + ";\r\n"
    }
      
    function Initialisation(prefix : String) : String
    {
      var i : int
      var text : String = ""
      var child : Object
        
      for (i = 0; i < owner.ChildCount; i++)
      {
        child = owner.Children[i]
        if (child instanceof IGenerateSource)
        {
          text  += IGenerateSource(child).Initialisation(prefix)
        }
      }

      text += "\r\n"
      text += prefix + "//\r\n"
      text += prefix + "// " + identifier + "\r\n"
      text += prefix + "//\r\n"
      text += prefix + identifier + " = new " + typeName + ";\r\n"
      text += prefix + identifier + ".Location = new System.Drawing.Point(" + owner.Left + ", " + owner.Top + ");\r\n"
      text += prefix + identifier + ".Size = new System.Drawing.Size(" + owner.Width + ", " + owner.Height + ");\r\n"
      text += prefix + identifier + ".Name = \"" + identifier + "\";\r\n"
      text += prefix + identifier + ".Anchor = " + GenericControl.GetAnchorStyles(owner.Stretch, owner.Alignment) + ";\r\n"

      for (i = 0; i < owner.ChildCount; i++)
      {
        child = owner.Children[i]
        if (child instanceof IGenerateSource)
        {
          text += prefix + identifier + ".Controls.Add(" + IGenerateSource(child).Identifier + ");\r\n"
        }
      }
        
      return text
    }
    
    function SupportingCode(prefix : String) : String
    {
      var i : int
      var text : String = ""
      var child : Object
        
      for (i = 0; i < owner.ChildCount; i++)
      {
        child = owner.Children[i]
        if (child instanceof IGenerateSource)
        {
          text  += IGenerateSource(child).SupportingCode(prefix)
        }
      }
      
      return text
    }

  }

  class PaddedPanel extends PaddedLayout implements IGenerateSource
  {
    var generator : GenericPanel
      
    function PaddedPanel(identifier : String, alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
      generator = new GenericPanel(identifier, this)
    }
      
    function get Identifier() : String { return generator.Identifier }
    function get TypeName() : String { return generator.TypeName }
      
    function Declaration(prefix : String) : String { return generator.Declaration(prefix) }
    function Initialisation(prefix : String) : String { return generator.Initialisation(prefix) }
    function SupportingCode(prefix : String) : String { return generator.SupportingCode(prefix) }
  }

  class HorizontalPanel extends HorizontalLayout implements IGenerateSource
  {
    var generator : GenericPanel
      
    function HorizontalPanel(identifier : String, alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
      generator = new GenericPanel(identifier, this)
    }
      
    function get Identifier() : String { return generator.Identifier }
    function get TypeName() : String { return generator.TypeName }
      
    function Declaration(prefix : String) : String { return generator.Declaration(prefix) }
    function Initialisation(prefix : String) : String { return generator.Initialisation(prefix) }
    function SupportingCode(prefix : String) : String { return generator.SupportingCode(prefix) }
  }

  class VerticalPanel extends VerticalLayout implements IGenerateSource
  {
    var generator : GenericPanel
      
    function VerticalPanel(identifier : String, alignment : AlignmentType, padding : int)
    {
      super(alignment, padding)
      generator = new GenericPanel(identifier, this)
    }
      
    function get Identifier() : String { return generator.Identifier }
    function get TypeName() : String { return generator.TypeName }
      
    function Declaration(prefix : String) : String { return generator.Declaration(prefix) }
    function Initialisation(prefix : String) : String { return generator.Initialisation(prefix) }
    function SupportingCode(prefix : String) : String { return generator.SupportingCode(prefix) }
  }

  class Form extends PaddedLayout implements IGenerateSource
  {
    protected var className : String
    protected var typeName : String
    protected var text : String
      
    function get Identifier() : String { return className }
    function get TypeName() : String { return typeName }
    function get Text() : String { return text }
      
    function Form(className : String, text : String, padding : int)
    {
      super(0, padding)
      this.className = className
      this.text = text
      typeName = "System.Windows.Forms.Form"
    }
       
    function Declaration(prefix : String) : String
    {
      var i : int
      var declaration : String = ""
      var child : IGenerateSource
      var childRectangle : IRectangle
      var source : String
      var doubleIndent : String = prefix + "  "
      var tripleIndent : String = doubleIndent + "  "
      
  @if (@interface_bugs)
      child = IGenerateSource(GetChild(0))
      childRectangle = IRectangle(GetChild(0))
  @else
      child = children[0]
      childRectangle = IRectangle(child)
  @end

	  
	  
	  
      source  = prefix + "import System;\r\n"
      source += prefix + "import System.Windows.Forms;\r\n"
      source += prefix + "import System.ComponentModel;\r\n"
      source += prefix + "import System.Drawing;\r\n"

      source += "\r\n"
      source += "\r\n"
      source += "package " + className + "NameSpace { \r\n"
      source += "\r\n"
      source += prefix + "//\r\n"
      source += prefix + "// " + className + "\r\n"
      source += prefix + "// The name of this class comes from the <Form>'s \"name\" attribute\r\n" 
	  source += prefix + "// If you do not specify a \"name\", xmlForm generates one for you\r\n"       
      source += prefix + "//\r\n"
      source += prefix + "class " + className + " extends " + TypeName + "\r\n" + prefix + "{\r\n"
      source += child.Declaration(doubleIndent)

      source += "\r\n"
      source += doubleIndent + "//\r\n"
      source += doubleIndent + "// Constructor\r\n"
      source += doubleIndent + "//\r\n"
      source += doubleIndent + "function " + className + "()\r\n" + doubleIndent + "{\r\n"
      source += tripleIndent + "SuspendLayout();\r\n"
      source += tripleIndent + "Text = \"" + text + "\";\r\n"
      source += tripleIndent + "// Text represents the form's caption, set this using the\r\n"
      source += tripleIndent + "// <Form>'s \"text\" attribute\r\n"
      
      source += child.Initialisation(tripleIndent)

      source += "\r\n"
      source += tripleIndent  + "ClientSize = new System.Drawing.Size(" + (childRectangle.Width + 2 * padding)
        + ", " + (childRectangle.Height + 2 * padding)+ ");\r\n"
      source += tripleIndent  + "Controls.Add(" + child.Identifier + ");\r\n"
      source += tripleIndent  + "StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\r\n"
      source += tripleIndent  + "// Change the Form's font below - NOTE: you may have to adjust the width of some controls after changing the form's font\r\n"
      source += tripleIndent  + "//Font = new System.Drawing.Font(\"Arial\", float(9.75), System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, byte(0));\r\n"
  	  source += tripleIndent  + "// Handle the Form's Load event - gets fired just before the system renders the form \r\n"
	  source += tripleIndent  + "//add_Load(yourFormsLoadHandlerHere);\r\n"
  	  source += tripleIndent  + "// Handle the Form's Close event - gets fired just after the system closes the form \r\n"
      source += tripleIndent  + "//add_Closing(yourFormsCloseHandlerHere);\r\n"
      source += tripleIndent + "ResumeLayout();\r\n"
      source += doubleIndent + "}\r\n"

      source += child.SupportingCode(doubleIndent)

      source += "\r\n"

      source += prefix + "}\r\n"
      source += prefix + "\r\n} // package \r\n"
          
      return source
    }
      
    function Initialisation(prefix : String) : String
    {
      return prefix + "Application.Run(new " + className +"NameSpace." + className + ");\r\n"
    }
      
    function SupportingCode(prefix : String) : String
    {
      return ""
    }
  }
}
