class Chemical < Sequel::Model(DB[:Chemical])

  include Comparable

  files = %w[
    util
    cluster
  ]
  files.each { |f| require_relative "region/#{f}" }

  ### SEQUEL

  unrestrict_primary_key
  many_to_many :neuronsets,
    :class=>:Neuronset,
    :join_table=>:ChemicalNeuronsetRel

  ### ACCESSORS

  attr_writer :data

  def data
    @data ||= Cluster.new(string: name).build(:hash_rep)
  end

  readers = Hash[
    :chemicals => proc { positive + negative + compound_negative },
    :positive => proc { data[:positive] or [] },
    :negative => proc { data[:negative] or [] },
    :compound_negative => proc { data[:compound_negative] or [] },
    :non_nts => proc { chemicals - Chemical.nt },
    :nts => proc { chemicals - Chemical.non_nt },
    :positive_non_nts => proc { positive & non_nts },
    :negative_non_nts => proc { negative & non_nts },
    :positive_nts => proc { positive & nts },
    :negative_nts => proc { negative & nts },
  ]
  readers.each { |k,v| define_method(k,&v) }

  ### PREDICATES

  extend Classifier
  numerical_predicates *readers.keys
  presence_predicates *readers.keys
  [ '', '_nts', '_non_nts' ].each do |meth|
    pos_short = "pos#{meth}"; neg_short = "neg#{meth}"
    alias_method pos_short, "positive#{meth}"
    alias_method neg_short, "negative#{meth}"
    numerical_predicates pos_short, neg_short; 
    presence_predicates pos_short, neg_short;
  end

  ### STRINGS

  alias_method :to_s, :name
  def english
    pos = positive.map(&[:+, '+']); neg = negative.map(&[:+, '-']) 
    comp_neg = compound_negative.map { |cn| '~' + cn.bracket('(') }
    [*pos, *neg, *comp_neg].join(', ')
  end

  ### COMPARISON

  def max_chemical; chemicals.max_by { |c| Chemical.chemicals.index(c) }; end
  def <=>(other); max_chemical <=> other.max_chemical; end

  ### DUMMY

  # the dummy is used for predicates when a neuronset has no chemical
  @dummy = new; @dummy.data = Hash.new([])
  class << self; attr_accessor :dummy; end


  ######################################
  ######################################
  ######################################
  ### DEPRECATED

end
