/*
 *  Implementation of COSS Relationship Service for MICO
 *  Copyright (C) 1998 Karel Gardas with the assistance of Kay Roemer
 *                                                       & Arno Puder
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Library General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library 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.  See the GNU
 *  Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public
 *  License along with this library; if not, write to the Free
 *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Send comments and/or bug reports to:
 *                 mico@informatik.uni-frankfurt.de
 *  or to my private e-mail:
 *                 gardask@alpha.inf.upol.cz
 */


#include <iostream.h>
#include <fstream.h>
#include <mico/CosRelationships.h>
#include <mico/RelationshipIterator_impl.h>

//#define DEBUG 1


RelationshipIterator_impl::RelationshipIterator_impl 
(CosRelationships::RelationshipHandles handles)
{
  rel_handles = handles;
  index = 0;
}


RelationshipIterator_impl::RelationshipIterator_impl (CORBA::Object_ptr obj)
  : CosRelationships::RelationshipIterator_skel (obj)
{

  CORBA::ORB_ptr orb = _orb ();

  int length = 0;
  char s[1000];
  ifstream in (obj->_ident ());
  in >> s;  // --iterator--
  in >> length;

#if DEBUG
  cout << "  <RelationshipIterator_impl> length = " << length << "\n";
  cout << "  <RelationshipIterator_impl> restoring rel_handles" << flush;
#endif

  rel_handles.length (length);
  for(int i=0; i<length; i++) {
#if DEBUG
    cout << "." << flush;
#endif
    in >> s;
    CORBA::Object_var obj = orb->string_to_object (s);
    CosRelationships::Relationship_ptr tmp_rel
      = CosRelationships::Relationship::_narrow (obj);
      rel_handles[i].the_relationship
        = CosRelationships::Relationship::_duplicate (tmp_rel);
      CORBA::Long tmp_id;
      in >> tmp_id;
      rel_handles[i].constant_random_id = tmp_id;
  }
  in >> index;
#if DEBUG
  cout << "done.\n";
#endif
  
  in.close ();

}


CORBA::Boolean
RelationshipIterator_impl::_save_object ()
{
  CORBA::ORB_ptr orb = _orb ();

  int length = rel_handles.length ();

  ofstream out (_ident ());
  assert (out);
  out << "--iterator--\n";
  out << length <<"\n";
#if DEBUG
  cout << "  <RelationshipIterator_impl> length = " << length << "\n";
  cout << "  <RelationshipIterator_impl> saving rel_handles" << flush;
#endif

  for(int i=0; i<length; i++) {
#if DEBUG
    cout << "." << flush;
#endif
    out << orb->object_to_string (rel_handles[i].the_relationship) << "\n";
    out << rel_handles[i].constant_random_id << "\n";
  }

#if DEBUG
  cout << "done.\n" << flush;
  cout << "  <RelationshipIterator> index = " << index << "\n";
#endif

  
  out << index << "\n";
  out.close ();
  
  return TRUE;
}


CORBA::Boolean
RelationshipIterator_impl::next_one 
(CosRelationships::RelationshipHandle*& rel)
{
#if DEBUG
  cout << "  <RelationshipIterator_impl> next_one (...);\n";
#endif
  if ( (rel_handles.length () - 1) < (CORBA::ULong)index) {
    return FALSE;
  }
  
  CosRelationships::RelationshipHandle*
    tmp = new CosRelationships::RelationshipHandle;
  tmp->constant_random_id = rel_handles[index].constant_random_id;
  tmp->the_relationship = CosRelationships::Relationship::_duplicate
    (rel_handles[index].the_relationship);
  rel = tmp;
  index++;
  return TRUE;
}

CORBA::Boolean
RelationshipIterator_impl::next_n (CORBA::ULong how_many,
				   CosRelationships::RelationshipHandles*& rel)
{
#if DEBUG
  cout << "  <RelationshipIterator_impl> next_n (...);\n";
#endif

  if ( (rel_handles.length () - 1) < (CORBA::ULong)index)
    return FALSE;

  long my_how_many;

  if ((rel_handles.length () - 1) < index + how_many - 1)
    my_how_many = rel_handles.length () - index;
  else
    my_how_many = how_many;

  CosRelationships::RelationshipHandles* tmp;
  tmp = new CosRelationships::RelationshipHandles;

  tmp->length (my_how_many);
#if DEBUG
  cout << "  <RelationshipIterator_impl> saving" << flush;
#endif
  for (int i=0; i<my_how_many; i++) {
#if DEBUG
    cout << "." << flush;
#endif
    (*tmp)[i].constant_random_id = rel_handles[i + index].constant_random_id;
    (*tmp)[i].the_relationship = CosRelationships::Relationship::_duplicate
      (rel_handles[i + index].the_relationship);
  }
#if DEBUG
  cout << "done.\n";
  cout << "  <RelationshipIterator_impl> length: " << tmp->length () << "\n";
#endif
  rel = tmp;
  index += my_how_many;
  return TRUE;
}


void
RelationshipIterator_impl::hello ()
{
  cout << "HELLO!\n";
}


void
RelationshipIterator_impl::destroy ()
{
  CORBA::BOA_var boa = _boa();
  CORBA::ORB_var orb = _orb();

  boa->deactivate_obj (this);
  orb->shutdown (TRUE);
}



CORBA::Boolean
RelationshipIteratorLoader::restore (CORBA::Object_ptr obj)
{
#if DEBUG
  cout << "  <RelationshipIterator_impl> restoring...\n";
#endif
  if (strcmp (obj->_repoid (), 
	      "IDL:omg.org/CosRelationships/RelationshipIterator:1.0") == 0) {
#if DEBUG
    cout << "  <RelationshipIterator_impl> "
	 << "create new RelationshipIterator_impl\n";
#endif
    new RelationshipIterator_impl (obj);
    return TRUE;
  }
  cout << "can't restore: " << obj->_repoid () << "\n";
  return FALSE;

}
