/*********************************************************
** Copyright (c) 2005
** University of Washington
** Licensed under the terms set forth by University of
** Washington. If you did not sign such a license, you
** are using this software/code illegally and you do not
** have permission to use, modify, or redistribute
** this or any files in this software package.
**
** File: Rintf_threads.cpp  $Revision: 236 $
**
**********************************************************/
#include "Rintf_threads.h"

#ifdef __cplusplus
extern "C" {
#endif
  SEXP GetProgressValues(SEXP sthreadid)
  {
    int i = 0;
    THREAD_ID_T threadid;
    
    SEXP sval, slist, snames;
    PROTECT(sthreadid = AS_INTEGER(sthreadid));
    threadid = (THREAD_ID_T)INTEGER_VALUE(sthreadid);
    
    CProgressThread* ppt = CProgressThreadManager::GetProgressThread(threadid);
    if(NULL == ppt)
      {
	Rf_error("Could not get information for thread id %d", threadid);
	UNPROTECT(1);
	return R_NilValue;
      }
    
    ppt->LockAll();
    
    static int SLIST_COUNT=6;
    PROTECT(slist = allocVector(VECSXP, SLIST_COUNT));
    PROTECT(snames = allocVector(STRSXP, SLIST_COUNT));
    
    PROTECT(sval=NEW_NUMERIC(1));
    NUMERIC_POINTER(sval)[0] = ppt->GetProgressInfoMax();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("max"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    PROTECT(sval=NEW_NUMERIC(1));
    NUMERIC_POINTER(sval)[0] = ppt->GetProgressInfoCurrent();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("current"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    PROTECT(sval=NEW_INTEGER(1));
    INTEGER_POINTER(sval)[0] = ppt->GetIsFinished();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("done"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    PROTECT(sval=NEW_INTEGER(1));
    INTEGER_POINTER(sval)[0] = ppt->GetIsCanceled();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("canceled"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    PROTECT(sval=NEW_INTEGER(1));
    INTEGER_POINTER(sval)[0] = (int)ppt->GetThreadId();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("threadid"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    PROTECT(sval=NEW_INTEGER(1));
    INTEGER_POINTER(sval)[0] = ppt->GetProgressInfoMsgId();
    SET_STRING_ELT(snames, i, CREATE_STRING_VECTOR("msgid"));
    SET_VECTOR_ELT(slist, i, sval);
    i++;
    
    ppt->UnlockAll();

    setAttrib(slist, R_NamesSymbol, snames);
    
    UNPROTECT(SLIST_COUNT + 3);
    return slist;
  }
  
  SEXP DeleteThread(SEXP sthreadid)
  { 
    SEXP sret;
    PROTECT(sthreadid = AS_INTEGER(sthreadid));
    THREAD_ID_T threadid = (THREAD_ID_T)INTEGER_VALUE(sthreadid);
    PROTECT(sret = NEW_INTEGER(1));

    CProgressThread* ppt = CProgressThreadManager::GetProgressThread(threadid);
    if(NULL == ppt)
      {
	Rf_error("Could not get information for thread id %d", threadid);
	UNPROTECT(2);
	return R_NilValue;
      }

    if(!ppt->GetIsFinished())
      ppt->Stop();

    CProgressThreadManager::Erase(threadid);
    delete ppt;

    INTEGER_POINTER(sret)[0] = 0;

    UNPROTECT(2);
    return sret;
  }

  SEXP StopThread(SEXP sthreadid)
  {
    SEXP sret;
    PROTECT(sthreadid = AS_INTEGER(sthreadid));
    THREAD_ID_T threadid = (THREAD_ID_T)INTEGER_VALUE(sthreadid);
    PROTECT(sret = NEW_INTEGER(1));

    CProgressThread* ppt = CProgressThreadManager::GetProgressThread(threadid);
    if(NULL == ppt)
      {
	Rf_error("Could not get information for thread id %d", threadid);
	UNPROTECT(2);
	return R_NilValue;
      }

    INTEGER_POINTER(sret)[0] = ppt->Stop();
    UNPROTECT(2);
    return sret;
  }

#ifdef __cplusplus
}
#endif
