

module ActiveRecord
    
    
    
    class Migration
        
        @@tableList = Array.new
        
        instance = Migration.new
        
        # class << self
        #          
        #            def tableList
        #                return instance.tableList
        #            end
        #            
        #            
        #        end
        
        
        def tableList
            return @@tableList
        end
        
        def quote_column_name(name)
            name
        end
        
        def native_database_types
            {}
        end
        
        def add_column_options!(sql, options) #:nodoc:
            sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
            sql << " NOT NULL" if options[:null] == false
        end
        
        def execute(sqlstring)
            
            
        end
        
        def add_index(table_name, column_name, options = {})
            column_names = Array(column_name)
            #index_name   = index_name(table_name, :column => column_names)
            
            if Hash === options # legacy support, since this param was a string
                index_type = options[:unique] ? "UNIQUE" : ""
                index_name = options[:name] || index_name
                else
                index_type = options
            end
            quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
            
            #STDERR.print "\nINDEX: found columns " + quoted_column_names +"\n";
            
            
            
            tableList.each_index{|index|
                #STDERR.print "\n item:"+tableList[index].name()
                
                #STDERR.print "|"+table_name.to_s()+"\n"
                #STDERR.print "\n"
                
                if (tableList[index].name() == table_name.to_s())
                    
                    tableList[index].index(index_name,quoted_column_names,options)
                end
            }
            
            
            
        end
        
        def create_table(name, options = {})
            
            #print "found table name ".append(name)
            
            
            
            tableDefinition = TableDefinition.new(self,options,name.to_s)
            
            
            yield tableDefinition
            
            result = ""
            
            
            
            #result += "<SQLTable>\n"
            
            #result += "<name>"+ name.to_s + "</name>\n"
            
            #result += tableDefinition.to_xml
            
            #result += "</SQLTable>\n"
            
            
            tableList << tableDefinition
            
            print result
        end
        
        def quote(value, column = nil)
            value
        end
        
        protected
        def options_include_default?(options)
            options.include?(:default) && !(options[:null] == false && options[:default].nil?)
        end
        
        
        class << self
        
        def tableList
            return @@tableList
        end
        
        
        
        def quote_column_name(name)
            name
        end
        
        def native_database_types
            {}
        end
        
        def add_column_options!(sql, options) #:nodoc:
            sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
            sql << " NOT NULL" if options[:null] == false
        end
        
        def execute(sqlstring)
            
            
        end
        
        def add_index(table_name, column_name, options = {})
            column_names = Array(column_name)
            #index_name   = index_name(table_name, :column => column_names)
            
            if Hash === options # legacy support, since this param was a string
                index_type = options[:unique] ? "UNIQUE" : ""
                index_name = options[:name] || index_name
                else
                index_type = options
            end
            quoted_column_names = column_names.map { |e| quote_column_name(e) }.join(", ")
            
            # STDERR.print "\nINDEX: found columns " + quoted_column_names +"\n";
            
            
            
            tableList.each_index{|index|
                #STDERR.print "\n item:"+tableList[index].name()
                
                #STDERR.print "|"+table_name.to_s()+"\n"
                #STDERR.print "\n"
                
                if (tableList[index].name() == table_name.to_s())
                    
                    tableList[index].index(index_name,quoted_column_names,options)
                end
            }
            
            
            
        end
        
        def create_table(name, options = {})
            
            #print "found table name ".append(name)
            
            
            
            tableDefinition = TableDefinition.new(self,options,name.to_s)
            
            
            yield tableDefinition
            
            result = ""
            
            
            
            #result += "<SQLTable>\n"
            
            #result += "<name>"+ name.to_s + "</name>\n"
            
            #result += tableDefinition.to_xml
            
            #result += "</SQLTable>\n"
            
            
            tableList << tableDefinition
            
            print result
        end
        
        def quote(value, column = nil)
            value
        end
        
        protected
        def options_include_default?(options)
            options.include?(:default) && !(options[:null] == false && options[:default].nil?)
        end
        
    end
    
    
    
end



class ColumnDefinition < Struct.new(:base, :name, :type, :limit, :precision, :scale, :default, :null,:options) #:nodoc:
    
    def sql_type
        base.type_to_sql(type.to_sym, limit, precision, scale) rescue type
    end
    
    
    
    def to_sql
        column_sql = "#{base.quote_column_name(name)} #{sql_type}"
        add_column_options!(column_sql, :null => null, :default => default) unless type.to_sym == :primary_key
        column_sql
    end
    alias to_s :to_sql
    
    private
    
    def add_column_options!(sql, options)
        base.add_column_options!(sql, options.merge(:column => self))
    end
end

class TableDefinition
    def initialize(base,options,name)
        @columns = []
        @base = base
        @options = options
        @name = name
        @indexes = []
        @relations = []
    end
	
	def name
		return @name
	end
    
    # Returns a ColumnDefinition for the column with name +name+.
    def [](name)
        @columns.find {|column| column.name.to_s == name.to_s}
    end
    
    def column(name, type, options = {})
        column = self[name] || ColumnDefinition.new(@base, name, type)
        column.limit = options[:limit] || native[type.to_sym][:limit] if options[:limit] or native[type.to_sym]
        column.precision = options[:precision]
        column.scale = options[:scale]
        column.default = options[:default]
        column.null = options[:null]
        if (options[:options])
            column.options = options[:options]
            else
            column.options = {}
        end
        @columns << column unless @columns.include? column
        self
    end
	
	def index(name, columnList, options = {})
        
		index = {}
		
    # split and trim each element
		index['columnList'] = columnList.split(",").map(&:strip)
		index['name'] = name
		index['options'] = options
		
		
		
		@indexes << index
		
	end
	
    
	
	def extract_options(argList)
        argList.last.is_a?(::Hash) ? argList.pop : {}
	end
	
	
	%w( string text integer float decimal datetime timestamp time date binary boolean ).each do |column_type|
    class_eval <<-EOV
    def #{column_type}(*args)
    options = extract_options(args)
    column_names = args
    
    column_names.each { |name| column(name, '#{column_type}', options) }
end
EOV
end

# Appends <tt>:datetime</tt> columns <tt>:created_at</tt> and
# <tt>:updated_at</tt> to the table.
def timestamps
    column(:created_at, :datetime)
    column(:updated_at, :datetime)
end

def references(*args)
    options = extract_options(args)
    polymorphic = options.delete(:polymorphic)
    
    
    
    
    
    args.each do |col|
        options = {}
        referenceOptions = {}
        
        referenceOptions['referencesTable'] = col
        referenceOptions['referencesColumn'] = 'id'
        
        options[:options] = referenceOptions
        
        column("#{col}_id", :integer, options)
        
    end
end
alias :belongs_to :references


# Returns a String whose contents are the column definitions
# concatenated together.  This string can then be pre and appended to
# to generate the final SQL to create the table.
def to_sql
    @columns * ', '
end

def to_xml
    result = ""
    
    result += "<SQLTable>\n"
    
    result += "<!--References supported-->\n";
    
    result += "<name>"+ name.to_s + "</name>\n"
    
    
    
    if (!@options[:id])
        result += "<SQLField>\n"
        result += "<name>id</name>\n<type>integer</type>\n"
		result += "<primaryKey>1</primaryKey>\n"
        result += "</SQLField>\n"
    end
    
    
    for column in @columns
        result += "<SQLField>\n"
        
        result += "<name><![CDATA[" + column.name.to_s + "]]></name>\n"
        result += "<type><![CDATA[" + column.type.to_s + "]]></type>\n"
        
        
        
        if (column.options.has_key?('referencesColumn'))
            result += "<referencesField><![CDATA[" + column.options['referencesColumn'].to_s + "]]></referencesField>\n"
        end
        
        if (column.options.has_key?('referencesTable'))
            result += "<referencesTable><![CDATA[" + column.options['referencesTable'].to_s + "]]></referencesTable>\n"
        end
		
		if (column.default)
			result += "<defaultValue><![CDATA[" + column.default.to_s + "]]></defaultValue>\n"
		end
		
		if (column.limit)
			result += "<typeSize><![CDATA[" + column.limit.to_s + "]]></typeSize>\n"
		end
		
		if (column.null == false)
			result += "<notNull>1</notNull>\n"
		end
		
        result += "</SQLField>\n"
    end
    
    for indexItem in @indexes
		
    # STDERR.print("\nA:"+indexItem['columnList'].to_s() +"\n")
        
		result += "<SQLIndex>\n"
		result += "<name>"+ indexItem['name'].to_s + "</name>\n"
        
        index_type = ""
        if Hash === indexItem['options'] # legacy support, since this param was a string
            index_type = indexItem['options'][:unique] ? "UNIQUE" : ""
            # index_name = options[:name] || index_name
            else
            index_type = indexItem['options']
        end
    
        if (index_type != "")
            
           result += "<indexType>"+index_type+"</indexType>\n"
        end
        
        
		if (indexItem['columnList'].size > 0)
            
            #STDERR.print("\nA:"+indexItem['columnList'].to_s() + " "+indexItem['columnList'].class.name.to_s() +"\n")
          
			for columnName in Array(indexItem['columnList'])
                #STDERR.print("\nFound Column: "+columnName.to_s+"\n")
				result += "<fieldName><![CDATA[" + columnName.to_s + "]]></fieldName>\n"
			end
            
			for columnName in Array(indexItem['columnList'])
				result += "<SQLIndexEntry>\n"
				result += "<name><![CDATA[" + columnName.to_s + "]]></name>\n"
				result += "</SQLIndexEntry>\n"
			end
		end
		result += "</SQLIndex>\n"
    end
    
    result += "</SQLTable>\n"
    
    result
end


private
def native
    @base.native_database_types
end

end


class Schema < ActiveRecord::Migration
    
	def self.test()
    print "test"
    print self.methods
end

def self.define(info={}, &block)
print "starting define method"
instance_eval(&block)

#unless info[:version].blank?
#initialize_schema_migrations_table
#assume_migrated_upto_version info[:version]
#end
end

end

end