// ---------------------------------------------------------------------------
// - Predcsm.cpp                                                             -
// - afnix:csm service - predicates implementation                           -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2013 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Ico.hpp"
#include "Cons.hpp"
#include "CartSet.hpp"
#include "Predcsm.hpp"
#include "Boolean.hpp"
#include "Assistant.hpp"
#include "Exception.hpp"
#include "SessionSet.hpp"
#include "LocalSpace.hpp"

namespace afnix {

  // this procedure checks that we have one argument only and returns
  // the evaluated object
  static inline Object* get_obj (Runnable* robj, Nameset* nset, Cons* args,
                                 const String& pname) {
    Object* car = nilp;
    if ((args == nilp) || (args->length () != 1))
      throw Exception ("argument-error", "illegal arguments with predicate",
                       pname);
    car = args->getcar ();
    return (car == nilp) ? nilp : car->eval (robj,nset);
  }

  // rcop: rco object predicate

  Object* csm_rcop  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "rco-p");
    bool result = (dynamic_cast <Rco*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // icop: rco object predicate

  Object* csm_icop  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "ico-p");
    bool result = (dynamic_cast <Ico*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // cartp: cart object predicate

  Object* csm_cartp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "cart-p");
    bool result = (dynamic_cast <Cart*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // csetp: cart set object predicate

  Object* csm_csetp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "cart-set-p");
    bool result = (dynamic_cast <CartSet*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // sessp: session object predicate
  
  Object* csm_sessp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "session-p");
    bool result = (dynamic_cast <Session*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // ssetp: session set object predicate
  
  Object* csm_ssetp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "session-set-p");
    bool result = (dynamic_cast <SessionSet*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // slotp: slot object predicate

  Object* csm_slotp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "slot-p");
    bool result = (dynamic_cast <Slot*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // apptp: appointer object predicate

  Object* csm_apptp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "appointer-p");
    bool result = (dynamic_cast <Appointer*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // asstp: assistant object predicate

  Object* csm_asstp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "assistant-p");
    bool result = (dynamic_cast <Assistant*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }


  // wspcp: workspace predicate

  Object* csm_wspcp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "workspace-p");
    bool result = (dynamic_cast <WorkSpace*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }

  // lspcp: localspace predicate

  Object* csm_lspcp  (Runnable* robj, Nameset* nset, Cons* args) {
    Object* obj = get_obj (robj, nset, args, "localspace-p");
    bool result = (dynamic_cast <LocalSpace*> (obj) == nilp) ? false : true;
    Object::cref (obj);
    return new Boolean (result);
  }
}
