#include <CORBA.h>
#include <unistd.h>
#include <iostream.h>

#include "Bank.h"
#include <mico/CosRelationships.h>
#include "Person.h"
#include "Ownership.h"
#include "Employment.h"
#include "Containment.h"
#include "Reference.h"
#include "Documents.h"



char c;
int object_type;
int object_count;
CosRelationships::NamedRoles named_roles;
int relationship_type;

// Objects ....

Account_ptr accounts[100];
CORBA::ULong account_index = 0;
Person_ptr persons[100];
CORBA::ULong person_index = 0;
Documents::Text_ptr texts[100];
CORBA::ULong text_index = 0;
Documents::Figure_ptr figures[100];
CORBA::ULong figure_index = 0;


// Roles and Relationships

CosRelationships::Role_ptr roles[100];
CORBA::ULong role_index = 0;
CosRelationships::Relationship_ptr rel_ships[100];
CORBA::ULong relship_index = 0;


// various factories

PersonFactory_var person_factory;
Bank_var bank;
Documents::FigureFactory_var figure_factory;
Documents::TextFactory_var text_factory;
CosRelationships::RoleFactory_var owner_factory; 
CosRelationships::RoleFactory_var ownedby_factory; 
CosRelationships::RoleFactory_var employer_factory; 
CosRelationships::RoleFactory_var employee_factory; 
CosRelationships::RoleFactory_var contains_factory; 
CosRelationships::RoleFactory_var containedin_factory; 
CosRelationships::RoleFactory_var references_factory; 
CosRelationships::RoleFactory_var referencedby_factory; 

CosRelationships::RelationshipFactory_var ownership_factory;
CosRelationships::RelationshipFactory_var employment_factory;
CosRelationships::RelationshipFactory_var containment_factory;
CosRelationships::RelationshipFactory_var reference_factory;


void clean () {
  cout << "                                                                            \r";
}

void newline () {
  cout << "\n";
}

void done () {
  cout << "done\n";
}

void list_person () {
  object_type = 1;
  newline ();
  cout << "List of persons:\n";
  newline ();
  for (CORBA::ULong i=1; i<=person_index; i++) {
    cout << i << ". " << flush;
    if (CORBA::is_nil (persons[i-1]))
      cout << "NIL\n";
    else {
      cout << persons[i-1]->first_name () << " " 
      << persons[i-1]->surname () << " - " << persons[i-1]->day () 
      << ". " << persons[i-1]->month () << ". "
      << " " << persons[i-1]->year () << "\n";
    }
  }
  newline ();
 
}

void list_account () {
  object_type = 2;
  newline ();
  cout << "List of accounts:\n";
  newline ();
  for (CORBA::ULong i=1; i<=account_index; i++) {
    cout << i << ". " << accounts[i-1]->name () << " "
         << " - " << accounts[i-1]->balance () << "\n";
  }
  newline ();

}

void list_text () {
  object_type = 3;
  newline ();
  cout << "List of texts:\n";
  newline ();
  for (CORBA::ULong i=1; i<=text_index; i++) {
    cout << i << ". " << texts[i-1]->name () << " "
         << " - " << texts[i-1]->file () << "\n";
  }
  newline ();

}

void list_figure () {
  object_type = 4;
  newline ();
  cout << "List of figures:\n";
  newline ();
  for (CORBA::ULong i=1; i<=figure_index; i++) {
    cout << i << ". " << figures[i-1]->name () << " "
         << " - " << figures[i-1]->file () << "\n";
  }
  newline ();
}

void print_list_object_menu () {
  cout << "1. person\n";
  cout << "2. account\n";
  cout << "3. text\n";
  cout << "4. figure\n";
  cout << "x - exit\n";
  cout << "\n";
  cout << "-> " << flush;
}

void list_object_menu () {
    print_list_object_menu ();
    cin >> c;
    switch (c)
      {
      case '1': list_person (); break;
      case '2': list_account (); break;
      case '3': list_text (); break;
      case '4': list_figure (); break;
      case 'x': return; break;
      }
}


void list_all_objects () {
  list_person ();
  list_account ();
  list_text ();
  list_figure ();
}

void list_roles () {
  newline ();
  cout << "List of roles: " << role_index << "\n";
  newline ();
  for (CORBA::ULong i=0; i<role_index; i++) {
    //cout << "xxx\n";
    if (!CORBA::is_nil (roles[i])) {
      //cout << i+1 << ". role isn't NULL\n";
      cout << i+1 << ". " << roles[i]->_repoid () << " - " << flush;
      Person_ptr tmp_person;
      if (tmp_person = Person::_narrow 
	  (roles[i]->related_object ())) {
	cout << tmp_person->first_name () << " " 
	     << tmp_person->surname () << "\n";
      }
      Account_ptr tmp_account;
      if (tmp_account = Account::_narrow
          (roles[i]->related_object ())) {
	cout << tmp_account->name () << " " << tmp_account->balance () << "\n";
      }
      Documents::Text_ptr tmp_text;
      if (tmp_text = Documents::Text::_narrow 
          (roles[i]->related_object ())) {
	cout << tmp_text->name () << " " << tmp_text->file () << "\n";
      }
      Documents::Figure_ptr tmp_figure;
      if (tmp_figure = Documents::Figure::_narrow 
          (roles[i]->related_object ())) {
	cout << tmp_figure->name () << " " << tmp_figure->file () << "\n";
      }
    }
  } 
  newline ();
}
  

void list_relationships () {
  CosRelationships::NamedRoles* tmp_named_roles;
  newline ();
  cout << "List of relationships: " << relship_index << "\n";
  newline ();
  for (CORBA::ULong i=0; i<relship_index; i++) {
    //cout << "xxx\n";
    if (!CORBA::is_nil (rel_ships[i])) {
      //cout << i+1 << ". role isn't NULL\n";
      cout << i+1 << ". " << rel_ships[i]->_repoid () << "\n";
      tmp_named_roles = rel_ships[i]->named_roles ();
      for (CORBA::ULong j=0; j<tmp_named_roles->length (); j++) {
	cout << "\t" << j+1 << ". " << (*tmp_named_roles)[j].name.in() << " - " 
	     << flush;
	
	Person_ptr tmp_person;
	if (tmp_person = Person::_narrow 
	    ((*tmp_named_roles)[j].aRole->related_object ())) {
	  cout << tmp_person->first_name () << " " 
	       << tmp_person->surname () << "\n";
	}
	Account_ptr tmp_account;
	if (tmp_account = Account::_narrow
	    ((*tmp_named_roles)[j].aRole->related_object ())) {
	  cout << tmp_account->name () << " " << tmp_account->balance () 
	       << "\n";
	}
	Documents::Text_ptr tmp_text;
	if (tmp_text = Documents::Text::_narrow 
	    ((*tmp_named_roles)[j].aRole->related_object ())) {
	  cout << tmp_text->name () << " " << tmp_text->file () << "\n";
	}
	Documents::Figure_ptr tmp_figure;
	if (tmp_figure = Documents::Figure::_narrow 
	    ((*tmp_named_roles)[j].aRole->related_object ())) {
	  cout << tmp_figure->name () << " " << tmp_figure->file () << "\n";
	}
      }
    } 
    newline ();
  }
}


void create_person () {
  char s1[100];
  char s2[100];
  long rc, d, m, y;
  cout << "create person:\n";
  cout << "name? " << flush;
  cin >> s1;
  cout << "surname? " << flush;
  cin >> s2;
  cout << "day? " << flush;
  cin >> d;
  cout << "month? " << flush;
  cin >> m;
  cout << "year? " << flush;
  cin >> y;
  cout << "number? " << flush;
  cin >> rc;
  persons[person_index] = person_factory->create (rc, y, m, d);
  persons[person_index]->first_name (s1);
  persons[person_index]->surname (s2);

  if (!CORBA::is_nil (persons[person_index]))
    person_index++;
  newline ();
}

void create_account () {
  char s1[100];
  int  b = 0;
  cout << "create account:\n";
  cout << "name? " << flush;
  cin >> s1;
  cout << "balance? " << flush;
  cin >> b;
  accounts[account_index] = bank->create ();
  accounts[account_index]->set (0);
  accounts[account_index]->name (s1);
  accounts[account_index]->deposit (b);
  if (!CORBA::is_nil (accounts[account_index]))
    account_index++;
  newline ();
}  

void create_text () {
  char s1[100];
  char s2[100];
  cout << "create text:\n";
  cout << "name? " << flush;
  cin >> s1;
  cout << "file? " << flush;
  cin >> s2;
  texts[text_index] = text_factory->create_with_file (s1, s2);
  if (!CORBA::is_nil (texts[text_index]))
    text_index++;
  newline ();
}

void create_figure () {
  char s1[100];
  char s2[100];
  cout << "create figure:\n";
  cout << "name? " << flush;
  cin >> s1;
  cout << "file? " << flush;
  cin >> s2;
  figures[figure_index] = figure_factory->create_with_file (s1, s2);
  if (!CORBA::is_nil (figures[figure_index]))
    figure_index++;
  newline ();
}

void print_create_object_menu () {
  cout << "1. person\n";
  cout << "2. account\n";
  cout << "3. text\n";
  cout << "4. figure\n";
  cout << "x - exit\n";
  cout << "\n";
  cout << "-> " << flush;
}

void create_object_menu () {
  int spatna = 0;
  for (;;) {
    print_create_object_menu ();
    cin >> c;
    switch (c)
      {
      case '1': create_person (); break;
      case '2': create_account (); break;
      case '3': create_text (); break;
      case '4': create_figure (); break;
      case 'x': return; break;
      }
  }
}

void create_owner () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = owner_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = owner_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = owner_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = owner_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}


void create_ownedby () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "object type: " << object_type << "\n";
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      //cout << "persons[object_count-1] is " << flush;
      //if (CORBA::is_nil (persons[object_count-1]))
      //	cout << "NIL!!!\n";
      //else
      //cout << "Object.\n";
      roles[role_index] = ownedby_factory->create_role 
	(Person::_duplicate (persons[object_count-1]));
	} 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = CosRelationships::Role::_duplicate
	(ownedby_factory->create_role (accounts[object_count-1]));
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = ownedby_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = ownedby_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    //cout << "inc role index\n";
    role_index++;
  }
  //cout << "role index: " << role_index << "\n";
  done ();

  if (roles[role_index-1] == NULL)
    cout << "created role is NULL\n";

  //cout << "created role is Object\n";
  //cout << "persons[object_count-1] is " << flush;
  //if (CORBA::is_nil (persons[object_count-1]))
  //  cout << "NIL!!!\n";
  //else
  //  cout << "Object.\n";
  
  newline ();
}

void create_employer () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = employer_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = employer_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = employer_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = employer_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}


void create_employee () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = employee_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = employee_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = employee_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = employee_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}

void create_contains () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = contains_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = contains_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = contains_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = contains_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}

void create_containedin () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = containedin_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = containedin_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = containedin_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = containedin_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}


void create_references () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = references_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = references_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = references_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = references_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}


void create_referencedby () {
  int ok = 1;
  cout << "From object of type:\n";
  newline ();
  list_object_menu ();
  cout << "-> " << flush;
  cin >> object_count;
  if (object_type == 1) {
    try {
      roles[role_index] = referencedby_factory->create_role (persons[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 2) {
    try {
      roles[role_index] = referencedby_factory->create_role (accounts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 3) {
    try {
      roles[role_index] = referencedby_factory->create_role (texts[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (object_type == 4) {
    try {
      roles[role_index] = referencedby_factory->create_role (figures[object_count-1]);
    } 
    catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
      {
	cout << "RelatedObjectTypeError!\n";
	ok = 0;
      }
    catch (CosRelationships::RoleFactory::NilRelatedObject_var &ex1)
      {
	cout << "NilRelatedObject!\n";
	ok = 0;
      }
  }
  if (ok) {
    role_index++;
  }
  done ();
  newline ();
}


void print_create_role_menu () {
  cout << "1. Owner\n";
  cout << "2. OwnedBy\n";
  cout << "3. Employer\n";
  cout << "4. Employee\n";
  cout << "5. Contains\n";
  cout << "6. ContainedIn\n";
  cout << "7. References\n";
  cout << "8. ReferencedBy\n";
  cout << "x - exit\n";
  cout << "\n";
  cout << "-> " << flush;
}

void create_role_menu () {
  for (;;) {
    print_create_role_menu ();
    cin >> c;
    switch (c)
      {
      case '1': create_owner (); break;
      case '2': create_ownedby (); break;
      case '3': create_employer (); break;
      case '4': create_employee (); break;
      case '5': create_contains (); break;
      case '6': create_containedin (); break;
      case '7': create_references (); break;
      case '8': create_referencedby (); break;
      case 'x': return; break;
      }
  }
}

void list_roles ();

void create_named_roles () {
  newline ();
  CORBA::ULong how_much;
  CORBA::ULong tmp;
  int good = 0;
  char name[100];
  cout << "Create Named Roles: - how much? " << flush;
  cin >> how_much;
  named_roles.length (how_much);
  for (CORBA::ULong i=0; i<how_much; i++) {
    list_roles ();
    newline ();
    cout << "Enter role number: " << flush;
    while (!good) {
      cin >> tmp;
      if (tmp < 1 || tmp > role_index) {
	cout << "Enter role number from 1 to " << role_index << ": " 
	     << flush;
	good = 0;
      }
      else
	good = 1;
    }
    good = 0;
    cout << "Enter role name: " << flush;
    cin >> name;
    named_roles[i].name = CORBA::string_dup (name);
    named_roles[i].aRole = CosRelationships::Role::_duplicate (roles[tmp-1]);
  }
}

void create_relationship () {
  try {
    if (relationship_type == 1) {
      rel_ships[relship_index] = ownership_factory->create (named_roles);
    }
    if (relationship_type == 2) {
      rel_ships[relship_index] = employment_factory->create (named_roles);
    }
    if (relationship_type == 3) {
      rel_ships[relship_index] = containment_factory->create (named_roles);
    }
    if (relationship_type == 4) {
      rel_ships[relship_index] = reference_factory->create (named_roles);
    }
  }
  catch (CosRelationships::RelationshipFactory::DegreeError_var &ex) {
    cout << "DegreeError exception!!!\n";
    cout << "Required degree is " << ex->required_degree << "\n";
    rel_ships[relship_index] = CosRelationships::Relationship::_nil ();
  }
  catch (CosRelationships::RelationshipFactory::DuplicateRoleName_var &ex) {
    cout << "DuplicateRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i<(ex->culprits).length () ; i++) {
      cout << i << ". name: " << (ex->culprits[i]).name.in() << "\n";
    }
    rel_ships[relship_index] = CosRelationships::Relationship::_nil ();
  }
  catch (CosRelationships::RelationshipFactory::UnknownRoleName_var &ex) {
    cout << "UnknownRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i< (ex->culprits).length (); i++) {
      cout << i << ". name: " << (ex->culprits[i]).name.in() << "\n";
    }
    rel_ships[relship_index] = CosRelationships::Relationship::_nil ();
    cout << "End of catch statement!\n";
  }
  catch (CosRelationships::RelationshipFactory::RoleTypeError_var &ex) {
    cout << "RoleTypeError exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i< (ex->culprits).length (); i++) {
      cout << i << ". name: " << (ex->culprits[i]).name.in() << "\n";
    }
    rel_ships[relship_index] = CosRelationships::Relationship::_nil ();
    cout << "End of catch statement!\n";
  }
  catch (CosRelationships::RelationshipFactory::MaxCardinalityExceeded_var &ex) {
    cout << "MaxCardinalityExceeded exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i< (ex->culprits).length (); i++) {
      cout << i << ". name: " << (ex->culprits[i]).name.in() << "\n";
    }
    rel_ships[relship_index] = CosRelationships::Relationship::_nil ();
    cout << "End of catch statement!\n";
  }


  if (!CORBA::is_nil (rel_ships[relship_index])) {
    cout << "done.\n";
    relship_index++;
  }
}


void create_ownership () {
  newline ();
  cout << "Create Ownership:\n";
  cout << "-----------------\n";
  create_named_roles ();
  relationship_type = 1;
  create_relationship ();
}

void create_employment () {
  newline ();
  cout << "Create Employment:\n";
  cout << "------------------\n";
  create_named_roles ();
  relationship_type = 2;
  create_relationship ();
}

void create_containment () {
  newline ();
  cout << "Create Containment:\n";
  cout << "-------------------\n";
  create_named_roles ();
  relationship_type = 3;
  create_relationship ();
}

void create_reference () {
  newline ();
  cout << "Create Reference:\n";
  cout << "-----------------\n";
  create_named_roles ();
  relationship_type = 4;
  create_relationship ();
}


void print_create_relationship_menu () {
  cout << "1. Ownership\n";
  cout << "2. Employment\n";
  cout << "3. Containment\n";
  cout << "4. Reference\n";
  cout << "x - exit\n";
  cout << "\n";
  cout << "-> " << flush;
}

void create_relationship_menu () {
  for (;;) {
    print_create_relationship_menu ();
    cin >> c;
    switch (c)
      {
      case '1': create_ownership (); break;
      case '2': create_employment (); break;
      case '3': create_containment (); break;
      case '4': create_reference (); break;
      case 'x': return; break;
      }
  }
}
       


void exit_client () {
  newline ();
  cout << "Exit (y/n) : " << flush;
  cin >> c;
  if (c == 'y' || c == 'Y') {
    cout << "Destroing all objects" << flush;
    for (CORBA::ULong i=0; i<relship_index; i++) {
      cout << "." << flush;
      rel_ships[i]->destroy ();
    }
    for (CORBA::ULong i=0; i<role_index; i++) {
      cout << "." << flush;
      roles[i]->destroy ();
    }
    for (CORBA::ULong i=0; i<person_index; i++) {
      cout << "." << flush;
      persons[i]->destroy ();
    }
    for (CORBA::ULong i=0; i<account_index; i++) {
      cout << "." << flush;
      accounts[i]->destroy ();
    }
    for (CORBA::ULong i=0; i<text_index; i++) {
      cout << "." << flush;
      texts[i]->destroy ();
    }
    for (CORBA::ULong i=0; i<figure_index; i++) {
      cout << "." << flush;
      figures[i]->destroy ();
    }
    cout << "done.\n";
    exit (0);
  }
  else {
    newline ();
    cout << "Well\n";
    newline ();
  }
}


void print_main_menu () {
  cout << "   Main menu\n";
  cout << "----------------------------\n";
  cout << "1. create object\n";
  cout << "2. create role\n";
  cout << "3. create relationship\n";
  cout << "4. list objects\n";
  cout << "5. list all objects\n";
  cout << "6. list roles\n";
  cout << "7. list relationships\n";
  //cout << "8. destroy role\n";
  //cout << "9. destroy relationship\n";
  cout << "x - exit\n";
  cout << "\n";
  cout << "-> " << flush;
}


int main_menu () {
  int end = 0;
  for (;;) {
    print_main_menu ();
    cin >> c;
    switch (c) 
      {
      case '1': create_object_menu (); break;
      case '2': create_role_menu (); break;
      case '3': create_relationship_menu (); break;
      case '4': list_object_menu (); break;
      case '5': list_all_objects (); break;
      case '6': list_roles (); break;
      case '7': list_relationships (); break;
      case 'x': exit_client (); break;
      }
  }
}



int main( int argc, char *argv[] )
{
  object_type = 0;
  object_count = 0;
  
  for (CORBA::ULong i=0; i<100; i++) {
    rel_ships[i] = NULL;
    roles[i] = NULL;
    persons[i] = NULL;
    accounts[i] = NULL;
    texts[i] = NULL;
    figures[i] = NULL;
  }

  //sleep (1);
  //ORB initialization
  CORBA::ORB_var orb = CORBA::ORB_init( argc, argv, "mico-local-orb" );
  CORBA::BOA_var boa = orb->BOA_init (argc, argv, "mico-local-boa");

  //sleep (1);
  // client side
  cout << "Client for demonstrating Relationship Service in MICO\n";
  //cout << "Testing arguments..." << flush;
  assert (argc == 2);
  //cout << "correct.\n";

  
  //sleep (1);
  cout << "Binding to AccountFactory\r" << flush ;
  CORBA::Object_var obj = orb->bind ("IDL:Bank:1.0", argv[1]);
  assert (!CORBA::is_nil (obj));
  if (!(bank = Bank::_narrow (obj))) {
    cout << "Binding to AccountFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to FigureFactory\r" << flush;
  CORBA::Object_var 
    obj100 = orb->bind ("IDL:Documents/FigureFactory:1.0", argv[1]);
  assert (!CORBA::is_nil (obj100));
  if (!(figure_factory = Documents::FigureFactory::_narrow (obj100))) {
    cout << "Binding to FigureFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to TextFactory\r" << flush;
  obj100 = orb->bind ("IDL:Documents/TextFactory:1.0", argv[1]);
  assert (!CORBA::is_nil (obj100));
  if (!(text_factory = Documents::TextFactory::_narrow (obj100))) {
    cout << "Binding to TextFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to OwnerRoleFactory\r" << flush;
  CORBA::ORB::ObjectTag_var 
    tag2 = CORBA::ORB::string_to_tag ("OwnerRole_impl");
  CORBA::Object_var obj10 
    = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag2,
		 argv[1]);
  assert (!CORBA::is_nil (obj10));
  if (!(owner_factory = CosRelationships::RoleFactory::_narrow(obj10))) {
    cout << "Binding to OwnerRoleFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to OwnedByRoleFactory\r" << flush;
  CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("OwnedByRole_impl");
  CORBA::Object_var obj11 
    = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(ownedby_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to OwnedByRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to EmployerRoleFactory\r" << flush;
  //  CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("EmployerRole_impl");
    //  CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(employer_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to EmployerRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to EmployeeRoleFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("EmployeeRole_impl");
    //CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(employee_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to EmployeeRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to ContainsRoleFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("ContainsRole_impl");
    //CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(contains_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to ContainsRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to ContainedInRoleFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("ContainedInRole_impl");
    //CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(containedin_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to ContainedInRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to ReferencesRoleFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("ReferencesRole_impl");
    //CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(references_factory = CosRelationships::RoleFactory::_narrow(obj11))) {
    cout << "Binding to ReferencesRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to ReferencedByRoleFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag3 = CORBA::ORB::string_to_tag ("ReferencedByRole_impl");
    //CORBA::Object_var 
    obj11 = orb->bind ("IDL:omg.org/CosRelationships/RoleFactory:1.0", 
		 tag3,
		 argv[1]);
  assert (!CORBA::is_nil (obj11));
  if (!(referencedby_factory = CosRelationships::RoleFactory::_narrow(obj11))){
    cout << "Binding to ReferencedByRoleFactory - ERROR!\n";
  }
  
  clean ();
  cout << "Binding to PersonFactory\r" << flush;
  CORBA::Object_var obj3 = orb->bind ("IDL:PersonFactory:1.0", argv[1]);
  assert (!CORBA::is_nil (obj3));
  if (!(person_factory = PersonFactory::_narrow(obj3))) {
    cout << "Binding to PersonFactory - ERROR!\n";
  }
  

  /*
  cout << "Binding to RelationshipFactory\r" << flush;
  CORBA::ORB::ObjectTag_var 
    tag10 = CORBA::ORB::string_to_tag ("Relationship_impl");
  CORBA::Object_var obj4 
    = orb->bind ("IDL:omg.org/CosRelationships/RelationshipFactory:1.0", 
		 tag10,
		 argv[1]);
  assert (!CORBA::is_nil (obj4));
  CosRelationships::RelationshipFactory_var rel_factory;
  if (rel_factory = CosRelationships::RelationshipFactory::_narrow(obj4))
    cout << "done.\n";
  else
    cout << "ERROR!\n";
    */


  clean ();
  cout << "Binding to OwnershipFactory\r" << flush;
  CORBA::ORB::ObjectTag_var 
    tag11 = CORBA::ORB::string_to_tag ("Ownership_impl");
  CORBA::Object_var obj30 
    = orb->bind ("IDL:omg.org/CosRelationships/RelationshipFactory:1.0", 
		 tag11,
		 argv[1]);
  assert (!CORBA::is_nil (obj30));
  if (!(ownership_factory 
	= CosRelationships::RelationshipFactory::_narrow(obj30))) {
    cout << "Binding to OwnershipFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to EmploymentFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag11 = CORBA::ORB::string_to_tag ("Employment_impl");
    //CORBA::Object_var 
    obj30 = orb->bind ("IDL:omg.org/CosRelationships/RelationshipFactory:1.0", 
		 tag11,
		 argv[1]);
  assert (!CORBA::is_nil (obj30));
  if (!(employment_factory 
	= CosRelationships::RelationshipFactory::_narrow(obj30))) {
    cout << "Binding to EmploymentFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to ContainmentFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag11 = CORBA::ORB::string_to_tag ("Containment_impl");
    //CORBA::Object_var 
    obj30 = orb->bind ("IDL:omg.org/CosRelationships/RelationshipFactory:1.0", 
		 tag11,
		 argv[1]);
  assert (!CORBA::is_nil (obj30));
  if (!(containment_factory 
	= CosRelationships::RelationshipFactory::_narrow(obj30))) {
    cout << "Binding to ContainmentFactory - ERROR!\n";
  }

  clean ();
  cout << "Binding to ReferenceFactory\r" << flush;
  //CORBA::ORB::ObjectTag_var 
    tag11 = CORBA::ORB::string_to_tag ("Reference_impl");
    //CORBA::Object_var 
    obj30 = orb->bind ("IDL:omg.org/CosRelationships/RelationshipFactory:1.0", 
		 tag11,
		 argv[1]);
  assert (!CORBA::is_nil (obj30));
  if (!(reference_factory 
	= CosRelationships::RelationshipFactory::_narrow(obj30))) {
    cout << "Binding to ReferenceFactory - ERROR!\n";
  }

  clean ();
  cout << "All Factories are OK!\n";
  newline ();
  main_menu ();

  /*
  cout << "\n";
  //sleep (1);
  accs[accs_index] = bank->create ();
  accs[accs_index]->name ("XKarel's_super_account:)))");
  accs_index++;
  accs[0]->deposit (1000);
  accs[accs_index] = bank->create ();
  accs[accs_index]->name ("Oluska's_super_account:-))");
  accs_index++;
  accs[1]->deposit (2000);
 
  cout << "account of name " << accs[0]->name () << " has "
       << accs[0]->balance() << " balance\n";
  cout << "account of name " << accs[1]->name () << " has "
       << accs[1]->balance() << " balance\n";

  texts[0] = text_factory->create_with_file ("Manon_Lescaut_Viteslav_Nezval", 
					     "manon.txt");
  texts_index++;
  figures[0] = figure_factory->create_with_file ("Cas_Salvator_Dali", 
						 "cas.jpg");
  figures_index++;
  cout  << "name and file of text: " << texts[0]->name () << ", " 
	<< texts[0]->file () << "\n";
  cout << "name and file of figure: " << figures[0]->name () << ", "
       << figures[0]->file () << "\n";
 
  texts[0]->destroy ();
  figures[0]->destroy ();
  persons[persons_index] = pfactory->create_with_name (7327, 1970, 7, 12, 
						       "Josef", "Novak");
  persons_index++;
  persons[persons_index] = pfactory->create_with_name (1893, 1950, 11, 1,
						       "Franta", "Voprsalku");
  persons_index++;
  
  cout << "name is " << persons[0]->first_name () << " " 
       << persons[0]->surname () << "\n";
  cout << "name is " << persons[1]->first_name () << " " 
       << persons[1]->surname () << "\n";


  cout << "Creating references role of " << texts[0]->name () << " ..."
       << flush;

  CORBA::Boolean right_references_role = TRUE;
  try {
    roles[roles_index] = references_factory->create_role (texts[0]);
  }  catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
    {
      cout << "RelatedObjectTypeError!\n";
      right_references_role = FALSE;
    }

  if (right_references_role) {
    cout << "done.\n";
    roles_index++;
  }


  cout << "Creating referencedby role of " << figures[0]->name () << " ..." 
       <<flush;


  CORBA::Boolean right_referencedby_role = TRUE;
  try {
    roles[roles_index] = referencedby_factory->create_role (figures[0]);
  }  catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
    {
      cout << "RelatedObjectTypeError!\n";
      right_referencedby_role = FALSE;
    }

  if (right_referencedby_role) {
    cout << "done.\n";
    roles_index++;
  }



  cout << "Creating employer role of " << persons[0]->first_name () << " "
       << persons[0]->surname () << "..." << flush;

  CORBA::Boolean right_employer_role = TRUE;
  try {
    roles[roles_index] = employer_factory->create_role (persons[0]);
  }  catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
    {
      cout << "RelatedObjectTypeError!\n";
      right_employer_role = FALSE;
    }

  if (right_employer_role) {
    cout << "done.\n";
    roles_index++;
  }


  cout << "Creating employee role of " << persons[1]->first_name () << " "
       << persons[1]->surname () << "..." << flush;

  CORBA::Boolean right_employee_role = TRUE;
  try {
    roles[roles_index] = employee_factory->create_role (persons[1]);
  }  catch (CosRelationships::RoleFactory::RelatedObjectTypeError_var &ex1)
    {
      cout << "RelatedObjectTypeError!\n";
      right_employee_role = FALSE;
    }

  if (right_employee_role) {
    cout << "done.\n";
    roles_index++;
  }


  Person_ptr tmp_person;

  tmp_person = Person::_narrow (roles[2]->related_object ());
  cout << "name of employer is " << tmp_person->first_name () 
       << " " << tmp_person->surname () << "\n";
  CORBA::release (tmp_person);

  tmp_person = Person::_narrow (roles[3]->related_object ());
  cout << "name of employee is " << tmp_person->first_name () 
       << " " << tmp_person->surname () << "\n";
  CORBA::release (tmp_person);


  CosRelationships::NamedRoles nr;
  nr.length (2);
  nr[0].name = CORBA::string_dup ("thing_with_references");
  nr[0].aRole = CosRelationships::Role::_duplicate (roles[0]);
  nr[1].name = CORBA::string_dup ("referenced_thing");
  nr[1].aRole = CosRelationships::Role::_duplicate (roles[1]);

  cout << "Creating reference between " << texts[0]->name ()
       << " and " << figures[0]->name () << " ..." << flush;
 
  try {
    rel_ships[relships_index] = reference_factory->create (nr);
  } 
  catch (CosRelationships::RelationshipFactory::DegreeError_var &ex) {
    cout << "DegreeError exception!!!\n";
    cout << "Required degree is " << ex->required_degree << "\n";
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
  } 
  catch (CosRelationships::RelationshipFactory::DuplicateRoleName_var &ex) {
    cout << "DuplicateRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i<(ex->culprits).length () ; i++) {
      cout << i << ". name: " << (ex->culprits[i]).name << "\n";
    }
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
  } 
  catch (CosRelationships::RelationshipFactory::UnknownRoleName_var &ex) {
    cout << "UnknownRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i< (ex->culprits).length (); i++) {
      cout << i << ". name: " << (ex->culprits[i]).name << "\n";
    }
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
    cout << "End of catch statement!\n";
  }

  if (!CORBA::is_nil (rel_ships[relships_index])) {
    cout << "done.\n";
    relships_index++;
  }



  //CosRelationships::NamedRoles nr;
  nr.length (2);
  nr[0].name = CORBA::string_dup ("employer");
  nr[0].aRole = CosRelationships::Role::_duplicate (roles[2]);
  nr[1].name = CORBA::string_dup ("employee");
  nr[1].aRole = CosRelationships::Role::_duplicate (roles[3]);

  cout << "Creating employment between " << persons[0]->first_name ()
       << " " << persons[0]->surname () << " and " << persons[1]->first_name ()
       << " " << persons[1]->surname () << " ..." << flush;
 
  try {
    rel_ships[relships_index] = employment_factory->create (nr);
  } 
  catch (CosRelationships::RelationshipFactory::DegreeError_var &ex) {
    cout << "DegreeError exception!!!\n";
    cout << "Required degree is " << ex->required_degree << "\n";
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
  } 
  catch (CosRelationships::RelationshipFactory::DuplicateRoleName_var &ex) {
    cout << "DuplicateRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i<(ex->culprits).length () ; i++) {
      cout << i << ". name: " << (ex->culprits[i]).name << "\n";
    }
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
  } 
  catch (CosRelationships::RelationshipFactory::UnknownRoleName_var &ex) {
    cout << "UnknownRoleName exception!!!\n";
    cout << "ex->culprits.length () = " << (ex->culprits).length () << "\n";
    for (CORBA::ULong i=0; i< (ex->culprits).length (); i++) {
      cout << i << ". name: " << (ex->culprits[i]).name << "\n";
    }
    rel_ships[relships_index] = CosRelationships::Relationship::_nil ();
    cout << "End of catch statement!\n";
  }

  if (!CORBA::is_nil (rel_ships[relships_index])) {
    cout << "done.\n";
    relships_index++;
  }

  Employment::Relationship_ptr empl 
    = Employment::Relationship::_narrow (rel_ships[(relships_index - 1)]);
  Employment::Date since;
  Employment::Date to;
  since.year = 1998;
  since.month = 3;
  since.day = 20;
  to.year = 2001;
  to.month = 12;
  to.day = 31;

  empl->since (since);
  empl->to (to);

  //boa->deactivate_obj (empl);

  cout << "since: " << empl->since ().day << ". " << empl->since ().month 
       << ". " << empl->since ().year << "\n";
  cout << "to: " << empl->to ().day << ". " << empl->to ().month 
       << ". " << empl->to ().year << "\n";




  CosRelationships::RelationshipIterator_var 
    iterator = CosRelationships::RelationshipIterator::_nil ();
  CosRelationships::RelationshipHandles* rel_handles;

  roles[0]->get_relationships (0, rel_handles, iterator);
  cout << "person->get_relationships (...)\n";
  cout << "iterator is " << flush;
  if (CORBA::is_nil (iterator))
    cout << "NIL!!!\n";
  else { 
    cout << "object!\n";
  }
  cout << "iterator->next_* (...)\n";
  CosRelationships::RelationshipHandles* tmp_rel_handles;
  CosRelationships::RelationshipHandle* tmp_rel_handle;
  //iterator->next_n (1, tmp_rel_handles);
  //iterator->hello ();
  //iterator->hello ();
  //iterator->hello ();
  //cout << "next_n done!\n";
  //if (iterator->next_one (tmp_rel_handle))
  //  cout << "next_one done!\n";
  //else
  //  cout << "next_one error!\n";
  //iterator->next_one (tmp_rel_handle);
  //iterator->destroy ();
  if (iterator->next_n (1, tmp_rel_handles))
    cout << "next_n done!\n";
  else
    cout << "next_n error!\n";
  
  CosRelationships::NamedRoles* tmp_named_roles;
  //tmp_named_roles = tmp_rel_handle->the_relationship->named_roles ();
  tmp_named_roles = (*tmp_rel_handles)[0].the_relationship->named_roles ();
  cout << "named_roles->length (): " << tmp_named_roles->length () << "\n";
  for (CORBA::ULong i=0; i<tmp_named_roles->length (); i++)
    cout << i << ". name is " << (*tmp_named_roles)[i].name << "\n";

  //cout << "Enter character:" << flush;
  //cin >> c;
  //cout << "Destroy statement:\n";
  //  cin >> c;
  //sleep (5);
  cout << "Destroing objects" << flush;

  if (!CORBA::is_nil (iterator)) {
    iterator->destroy ();
    cout << "i" << flush;
  }
  
  for (CORBA::ULong i=0; i<relships_index; i++)
  if (!CORBA::is_nil (rel_ships[i])) {
  rel_ships[i]->destroy ();
  cout << "r" << flush;
  }
  //sleep (5);
  for (CORBA::ULong i=0; i<roles_index; i++)
  if (!CORBA::is_nil (roles[i])) {
  roles[i]->destroy ();
  cout << "." << flush;
  }
  for (CORBA::ULong i=0; i<accs_index; i++)
  if (!CORBA::is_nil (accs[i])) {
  accs[i]->destroy ();
  cout << "." << flush;
  }
  for (CORBA::ULong i=0; i<persons_index; i++)
  if (!CORBA::is_nil (persons[i])) {
      persons[i]->destroy ();
      cout << "." << flush;
    }


    cout << "done.\n";

    */
    return 0;
}


