<%

###
### $Rev$
### $Release: 0.7.2 $
### copyright(c) 2005-2010 kuwata-lab all rights reserved.
###

if @describe
   sb = []
   sb << "  --module=name   :  module name in which class defined\n"
   sb << "  --parent=name   :  parent class name\n"
   sb << "  --include=name  :  module name which all classes include\n"
   sb << "  --initialize=false :  not print initialize() method\n"
   sb << "  --hashlike      :  include Kwalify::Util::HashLike module\n"
   #sb << "  --ggap          :  use generation gap pattern\n"
   return sb.join
end

require 'kwalify/util/ordered-hash'

def generate_classdef(schema)
  hash = Kwalify::Util::OrderedHash.new
  #hash.instance_eval { alias []= add }
  modname = @properties[:module]
  Kwalify::Util.traverse_schema(schema) do |rulehash|
    if rulehash['class']
      arr = _generate_classdef(rulehash)
      key = rulehash['class']
      classdef = modname ? arr.join('  ') : arr.join()
      #hash[key] = classdef if !hash.key?(key) || classdef != hash[key]
      hash[key] = classdef if !hash.key?(key) || classdef.length > hash[key].length
    end
  end
  sb = ''
  sb   << "require 'kwalify/util/hashlike'\n" if @properties[:hashlike]
  sb   << "\n"                                if @properties[:hashlike]
  sb   << "module #{@properties[:module]}\n"  if modname
  sb   << "\n"                                if modname
  hash.each do |classname, classdef|
    sb << classdef
    sb << "\n"
  end
  sb   << "end\n"                             if modname
  sb   << "\n"                                if modname
  return sb.chomp
end

def _generate_classdef(rulehash)
  return nil unless rulehash['class']
  assert unless rulehash['mapping']
  classname = rulehash['class']
  classname = classname + '_' if @properties[:ggap]
  extend = @properties[:parent] ? " < #{@properties[:parent]}" : nil
  flag_init = @properties[:initialize] != false
  arr = ['']
  arr      << "## #{rulehash['desc']}\n"
  arr      << "class #{classname}#{extend}\n"
  arr      << "  include Kwalify::Util::HashLike\n"  if @properties[:hashlike]
  arr      << "  include #{@properties[:include]}\n" if @properties[:include]
  arr1 = []
  arr2 = []   # accessors
  arr3 = []   # boolean accessors
  arr4 = []   # default values
  v = nil
  rulehash['mapping'].each do |name, map_rulehash|
    next unless name =~ /\A[a-zA-Z_][-\w]*\z/
    name2 = name.gsub(/-/, '_')
    var = "%-16s" % name2
    len = 13 - name2.length
    len = 0 if len < 0
    spc = ' ' * len
    arr2   << "  attr_accessor :#{var} # #{map_rulehash['type'] || 'str'}\n"
    flag_bool = (t = map_rulehash['type']) == 'bool' || t == 'boolean'
    arr3   << "  def #{name2}?#{spc};  @#{name2}#{spc}; end\n" if flag_bool
    arr4   << "      @#{var} = #{v.inspect}\n" unless (v=map_rulehash['default']).nil?
    if !flag_init
      # pass
    elsif map_rulehash['class']
      cname = map_rulehash['class']
      arr1 << "    @#{var} = (v=hash['#{name}']) && v.is_a?(Hash) ? #{cname}.new(v) : v\n"
    elsif map_rulehash['sequence'] && map_rulehash['sequence'][0]['class']
      item_rulehash = map_rulehash['sequence'][0]
      cname = item_rulehash['class']
      arr1 << "    @#{var} = (v=hash['#{name}']) ? v.map!{|e| e.is_a?(#{cname}) ? e : #{cname}.new(e)} : v\n"
    elsif map_rulehash.key?('default')
      #arr << "    @#{var} = hash.key?('#{name}') ? hash['#{name}'] : #{map_rulehash['default'].inspect}\n"
      arr1 << "    @#{var} = (v=hash['#{name}']).nil? ? #{map_rulehash['default'].inspect} : v\n"
    else
      arr1 << "    @#{var} = hash['#{name}']\n"
    end
  end
  arr      << "  def initialize(hash=nil)\n" if flag_init
  arr      << "    if hash.nil?\n"           if flag_init
  arr.concat arr4                            if flag_init
  arr      << "      return\n"               if flag_init
  arr      << "    end\n"                    if flag_init
  arr.concat arr1                            if flag_init
  arr      << "  end\n"                      if flag_init
  arr.concat(arr2)
  arr.concat(arr3)
  if @properties[:ggap]
    arr    << "end\n"
    arr    << "class #{rulehash['class']} < #{classname}\n"
  end
  arr      << "end\n"
  return arr
end

%> <%= generate_classdef(@schema) %>