#include <ruby.h>

/* Calls to Contrast modules and classes */
VALUE scope_interface;
VALUE scope_inst_methods, scope_mod, scope_klass;

/* IVs */
static VALUE rb_iv_cntr_scope;
static VALUE rb_iv_dslr_scope;
static VALUE rb_iv_split_scope;

/* Constants */
static VALUE rb_const_ec;
static VALUE rb_const_mon;
static VALUE rb_const_ec_keys;
static VALUE c_const_ctr_agent_app_scope;

/* Symbols */
static VALUE rb_sym_scope_mod;
static VALUE rb_sym_contrast;
static VALUE rb_sym_deserialization;
static VALUE rb_sym_split;

/* methods names - only reusable ones */
VALUE rb_method_name_init;
VALUE rb_method_name_in_scope;
VALUE rb_method_name_enter_scope;
VALUE rb_method_name_exit_scope;
VALUE rb_method_name_scope_for_current_ec;
VALUE rb_method_name_in_cntr_scope;
VALUE rb_method_name_enter_cntr_scope;
VALUE rb_method_name_exit_cntr_scope;
VALUE rb_method_name_in_dslr_scope;
VALUE rb_method_name_enter_dslr_scope;
VALUE rb_method_name_exit_dslr_scope;
VALUE rb_method_name_in_split_scope;
VALUE rb_method_name_enter_split_scope;
VALUE rb_method_name_exit_split_scope;
VALUE rb_method_name_split_scope_depth;

/* Scope class */
VALUE contrast_scope_klass_init(VALUE self, VALUE args);
VALUE in_cntr_scope(VALUE self, VALUE args);
VALUE enter_cntr_scope(VALUE self, VALUE args);
VALUE exit_cntr_scope(VALUE self, VALUE args);
VALUE in_split_scope(VALUE self, VALUE args);
VALUE enter_split_scope(VALUE self, VALUE args);
VALUE exit_split_scope(VALUE self, VALUE args);
VALUE split_scope_depth(VALUE self, VALUE args);
VALUE in_dsrl_scope_scope(VALUE self, VALUE args);
VALUE enter_dsrl_scope(VALUE self, VALUE args);
VALUE exit_dsrl_scope(VALUE self, VALUE args);
VALUE scope_klass_in_scope(VALUE self, VALUE method_scope_sym);
VALUE scope_klass_enter_scope(VALUE self, VALUE method_scope_sym);
VALUE scope_klass_exit_scope(VALUE self, VALUE method_scope_sym);

/* Scope interface */
VALUE contrast_scope_interface_init(VALUE self, VALUE args);
VALUE contrast_scope_for_current_ec(VALUE self, VALUE args);
VALUE contrast_scope_application_update();

/* Scope instance methods */
VALUE inst_methods_in_cntr_scope(VALUE self, VALUE args);
VALUE inst_methods_enter_cntr_scope(VALUE self, VALUE args);
VALUE inst_methods_exit_cntr_scope(VALUE self, VALUE args);
VALUE inst_methods_in_split_scope(VALUE self, VALUE args);
VALUE inst_methods_enter_split_scope(VALUE self, VALUE args);
VALUE inst_methods_exit_split_scope(VALUE self, VALUE args);
VALUE inst_methods_split_scope_depth(VALUE self, VALUE args);
VALUE inst_methods_in_dsrl_scope(VALUE self, VALUE args);
VALUE inst_methods_enter_dsrl_scope(VALUE self, VALUE args);
VALUE inst_methods_exit_dsrl_scope(VALUE self, VALUE args);
VALUE inst_methods_in_scope(VALUE self, VALUE method_scope_sym);
VALUE inst_methods_enter_scope(VALUE self, VALUE method_scope_sym);
VALUE inst_methods_exit_scope(VALUE self, VALUE method_scope_sym);

/* Scope components module */
VALUE scope_mod_sweep_dead_ecs(VALUE self, VALUE args);
VALUE inst_methods_enter_method_scope(VALUE self, VALUE scopes_to_enter);
VALUE inst_methods_exit_method_scope(VALUE self, VALUE scopes_to_exit);

/* Helpers */
VALUE is_in_scope(int scope);
VALUE get_ec();
VALUE rb_new_c_scope();
int scope_increase(int scope);
int scope_decrease(int scope);
void rb_raise_scope_no_method_err(const VALUE method_scope_sym);

void Init_cs__scope(void);