class SAP4Rails

  require 'SAP/Rfc'
  require 'yaml'

# These are shared by all
  @@conn_settings = {}
  @@first_mm = {}
  @@first_new = {}
  @@rfc = {}
  @@ifaces = {}

# these are overidden by successive inherits
  @@funcs = [ ]
  @@params = [ ]


# User defined instance methods
  def initialize(parms=[])
    RAILS_DEFAULT_LOGGER.warn("[#{self.class}]#initialize what did we get: " + parms.inspect)
    parms.each {|k, v|
      v.strip!
      eval "@" + k + " = v"
    }
    @errors = ActiveRecord::Errors.new(self)
  end

  def errors
    return @errors
  end

  def self.inherited(subclass)
    RAILS_DEFAULT_LOGGER.warn("[SAP4Rails] self.inherited: #{subclass}")

    # clear out any other classes that haven't been completed yet
    @@first_new.each_key{|k| 
      if ! @@first_new[k]
        RAILS_DEFAULT_LOGGER.warn("[SAP4Rails] not initialised yet: #{k}")
        eval "#{k}.new"
      end
    }

    # tracking for sub class initilisation
    @@first_mm[subclass.to_s] = nil
    @@first_new[subclass.to_s] = nil

    # push all the dynamic SAP stuf into the inheritor
    class_eval <<-EOS
    def #{subclass}.human_attribute_name(attrib)
      RAILS_DEFAULT_LOGGER.warn("[#{subclass}] human_attribute_name for: " + attrib.to_s)
      return attrib.to_s
    end

    def #{subclass}.check_connect
      RAILS_DEFAULT_LOGGER.warn("in check connect...")
      if ! @@first_mm[self.name]
        #{subclass}.load_config()
        RAILS_DEFAULT_LOGGER.warn("[" + self.name + "] building RFC connection with: " + @@conn_settings.inspect)
        @@rfc[self.name] = SAP::Rfc.new(:ashost => @@conn_settings['ashost'],
                                        :sysnr  => @@conn_settings['sysnr'],
                                        :lang   => @@conn_settings['lang'],
                                        :client => @@conn_settings['client'],
                                        :user   => @@conn_settings['user'],
                                        :passwd => @@conn_settings['passwd'],
                                        :trace  => @@conn_settings['trace'])
  
        RAILS_DEFAULT_LOGGER.warn("completed the connection ...")
      else
        RAILS_DEFAULT_LOGGER.warn("allready connected ...")
      end 
    end

    def #{subclass}.lookup_ifaces(interfaces=[])
      interfaces.each do |f|
        next if @@ifaces.has_key?(f)
        RAILS_DEFAULT_LOGGER.warn("loading " + f + " ...")
        @@ifaces[f] = @@rfc[self.name].discover(f)
        @@ifaces[f].rfc = @@rfc[self.name]
      end
      RAILS_DEFAULT_LOGGER.warn("[" + self.name + "] loaded the functions: " + interfaces.inspect + " ...")
    end 

    def #{subclass}.method_missing(methid, *rest)
      meth = methid.id2name
      RAILS_DEFAULT_LOGGER.warn("[" + self.name + "] missing_method: " + meth)
      RAILS_DEFAULT_LOGGER.warn("[" + self.name + "] init state: " + @@first_mm.inspect)
      if ! @@first_mm[self.name]
        check_connect()
        lookup_ifaces(@@funcs)
        @@first_mm[self.name] = 1
      end
      return @@ifaces.has_key?(meth.upcase) ? @@ifaces[meth.upcase] : nil
    end
    EOS
  end 

  cattr_accessor :configurations
  @@configurations = {}

  class << self
    def new(*args)
      if ! @@first_new[self.name]
        # figure out what accessors are required for the controller/view
        params = ""
        RAILS_DEFAULT_LOGGER.warn("[new] this is a: #{self.name}")
        RAILS_DEFAULT_LOGGER.warn("ARGS are: " + args.inspect)
        RAILS_DEFAULT_LOGGER.warn("PARAMS are: " + @@params.inspect)
        if @@params.length > 0
          params = "attr_accessor " + @@params.map!{|p| ":" + p}.join(", ")
        end
        RAILS_DEFAULT_LOGGER.warn("PARAMS to create: " + params)
        class_eval params
      end
      @@first_new[self.name] = 1
      return super(*args)
    end

    def load_config
      SAP4Rails.configurations = File.open("#{RAILS_ROOT}/config/sap.yml") { |f| YAML::load(f) }
      RAILS_DEFAULT_LOGGER.warn("[SAP4Rails] Configuration file: " + @@configurations.inspect)
      RAILS_DEFAULT_LOGGER.warn("[SAP4Rails] running in: " + RAILS_ENV + " mode")
      @@conn_settings = @@configurations[RAILS_ENV]
    end
  end

end

