#include "opus_jvm.h"

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::ListIterator
//
// Purpose:
//
//    ListIterator constructor
//
// Description:
//
//    Creates the base OPUS_jclass and saves a reference to the element
//    factory.
//
// Returns:
//
//    none
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
ListIterator<T>::ListIterator(const ListElementFactory* f, const jobject& jo)
                                              : OPUS_jclass(jo), factory(f)
{
   // empty block
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::~ListIterator
//
// Purpose:
//
//    ListIterator destructor
//
// Description:
//
//    A no-op.
//
// Returns:
//
//    none
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
ListIterator<T>::~ListIterator()
{
   // empty block
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::hasNext
//
// Purpose:
//
//    Test for next element in the iteration.
//
// Description:
//
//    Calls hasNext() method on the wrapped Java Iterator.
//
// Returns:
//
//    true if there is a next element;
//    false otherwise
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
bool ListIterator<T>::hasNext() const
{
   jmethodID mid = get_method_id("hasNext", "()Z");
   OPUS_JVM jvm = OPUS_JVM::instance();
   return jvm->CallBooleanMethod(this_obj, mid);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::hasPrevious
//
// Purpose:
//
//    Test for previous element in the iteration.
//
// Description:
//
//    Calls hasPrevious() method on the wrapped Java Iterator.
//
// Returns:
//
//    true if there is a previous element;
//    false otherwise
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
bool ListIterator<T>::hasPrevious() const
{
   jmethodID mid = get_method_id("hasPrevious", "()Z");
   OPUS_JVM jvm = OPUS_JVM::instance();
   return jvm->CallBooleanMethod(this_obj, mid);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::next
//
// Purpose:
//
//    Create next object in the iteration.
//
// Description:
//
//    Calls next() method on the wrapped Java Iterator and creates the
//    appropriate wrapper class off the heap.
//
// Returns:
//
//    A pointer to the element wrapper class created on the heap; the 
//    caller should call delete on the pointer when it is no longer needed.
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
T* ListIterator<T>::next() const
{
   jmethodID mid = get_method_id("next", "()Ljava/lang/Object;");
   OPUS_JVM jvm = OPUS_JVM::instance();
   jobject jo = jvm->CallObjectMethod(this_obj, mid);
   void* p = factory->create(jo);
   jvm->DeleteLocalRef(jo);
   return static_cast<T*>(p);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::nextIndex
//
// Purpose:
//
//    Get the index of the next element in the iteration.
//
// Description:
//
//    Calls nextIndex() method on the wrapped Java Iterator.
//
// Returns:
//
//    index of the next element in the container
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
int ListIterator<T>::nextIndex() const
{
   jmethodID mid = get_method_id("nextIndex", "()I");
   OPUS_JVM jvm = OPUS_JVM::instance();
   return jvm->CallIntMethod(this_obj, mid);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::previous
//
// Purpose:
//
//    Create previous object in the iteration.
//
// Description:
//
//    Calls previous() method on the wrapped Java Iterator and creates the
//    appropriate wrapper class off the heap.
//
// Returns:
//
//    A pointer to the element wrapper class created on the heap; the 
//    caller should call delete on the pointer when it is no longer needed.
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
T* ListIterator<T>::previous() const
{
   jmethodID mid = get_method_id("previous", "()Ljava/lang/Object;");
   OPUS_JVM jvm = OPUS_JVM::instance();
   jobject jo = jvm->CallObjectMethod(this_obj, mid);
   void* p = factory->create(jo);
   jvm->DeleteLocalRef(jo);
   return static_cast<T*>(p);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::previousIndex
//
// Purpose:
//
//    Get the index of the previous element in the iteration.
//
// Description:
//
//    Calls previousIndex() method on the wrapped Java Iterator.
//
// Returns:
//
//    index of the previous element in the container
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
int ListIterator<T>::previousIndex() const
{
   jmethodID mid = get_method_id("previousIndex", "()I");
   OPUS_JVM jvm = OPUS_JVM::instance();
   return jvm->CallIntMethod(this_obj, mid);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::remove
//
// Purpose:
//
//    Remove the next element in the iteration.
//
// Description:
//
//    Calls remove() method on the wrapped Java Iterator.
//
// Returns:
//
//    none
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
void ListIterator<T>::remove() const
{
   jmethodID mid = get_method_id("remove", "()V");
   OPUS_JVM jvm = OPUS_JVM::instance();
   jvm->CallVoidMethod(this_obj, mid);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::set
//
// Purpose:
//
//    Replace the next element in the iteration with the wrapped Java 
//    object.
//
// Description:
//
//    Calls set() method on the wrapped Java Iterator.
//
// Returns:
//
//    none
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
void ListIterator<T>::set(const T& t) const
{
   jmethodID mid = get_method_id("set", "(Ljava/lang/Object;)V");
   OPUS_JVM jvm = OPUS_JVM::instance();
   jobject jo = jobject(t);
   jvm->CallVoidMethod(this_obj, mid, jo);
   jvm->DeleteLocalRef(jo);
}

//////////////////////////////////////////////////////////////////////////
//
// Method: ListIterator<T>::add
//
// Purpose:
//
//    Add the wrapped Java object to the container.
//
// Description:
//
//    Calls add() method on the wrapped Java Iterator.
//
// Returns:
//
//    none
//
// Exceptions thrown:
//
//    none
//
// Example:
//
//    none
//
// Modification History:
//
// Date      OPR      Who         Reason
// --------- -------- ----------- ----------------------------------------
// 01/08/02  44751    WMiller     Initial code
//
//////////////////////////////////////////////////////////////////////////

template<class T>
void ListIterator<T>::add(const T& t) const
{
   jmethodID mid = get_method_id("add", "(Ljava/lang/Object;)V");
   OPUS_JVM jvm = OPUS_JVM::instance();
   jobject jo = jobject(t);
   jvm->CallVoidMethod(this_obj, mid, jo);
   jvm->DeleteLocalRef(jo);
}
