module NetSuite
  module Support
    module Fields
      include Attributes

      def self.included(base)
        base.send(:extend, ClassMethods)
      end

      module ClassMethods

        def fields(*args)
          if args.empty?
             @fields ||= Set.new
          else
            args.each do |arg|
              field arg
            end
          end
        end

        def field(name, klass = nil)
          name_sym = name.to_sym
          fields << name_sym
          if klass
            define_method(name_sym) do
              attributes[name_sym] ||= klass.new
            end

            define_method("#{name_sym}=") do |value|
              if value.nil?
                attributes.delete(name_sym)
              else
                attributes[name_sym] = value.kind_of?(klass) ? value : klass.new(value)
              end
            end
          else
            define_method(name_sym) do
              attributes[name_sym]
            end

            define_method("#{name_sym}=") do |value|
              attributes[name_sym] = value
            end
          end
        end

        def read_only_fields(*args)
          if args.empty?
             @read_only_fields ||= Set.new
          else
            args.each do |arg|
              read_only_field arg
            end
          end
        end

        def read_only_field(name)
          name_sym = name.to_sym
          read_only_fields << name_sym
          field name
        end

        # a bit of trickery: this is for classes which inherit from other classes
        # i.e. the AssemblyItem, KitItem, etc; this copies the superclass's fields over
        def inherited(klass)
          klass.instance_variable_set("@fields", self.fields)
          klass.instance_variable_set("@read_only_fields", self.read_only_fields)
        end
      end

    end
  end
end

module NetSuite
  module Support
    module Fields
      include Attributes

      def self.included(base)
        base.send(:extend, ClassMethods)
      end

      module ClassMethods

        def fields(*args)
          if args.empty?
             @fields ||= Set.new
          else
            args.each do |arg|
              field arg
            end
          end
        end

        def field(name, klass = nil)
          name_sym = name.to_sym
          fields << name_sym
          if klass
            define_method(name_sym) do
              attributes[name_sym] ||= klass.new
            end

            define_method("#{name_sym}=") do |value|
              if value.nil?
                attributes.delete(name_sym)
              else
                attributes[name_sym] = value.kind_of?(klass) ? value : klass.new(value)
              end
            end
          else
            define_method(name_sym) do
              attributes[name_sym]
            end

            define_method("#{name_sym}=") do |value|
              attributes[name_sym] = value
            end
          end
        end

        def read_only_fields(*args)
          if args.empty?
             @read_only_fields ||= Set.new
          else
            args.each do |arg|
              read_only_field arg
            end
          end
        end

        def read_only_field(name)
          name_sym = name.to_sym
          read_only_fields << name_sym
          field name
        end
      end

    end
  end
end

Remove class inheritance instance variable hack
Remove class inheritance instance variable hack
