/* $Id$ */
/* 
 * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pj/timer.h>
#include <pj/pool.h>
#include <pj/assert.h>
#include <pj/errno.h>
#include <pj/lock.h>

#include "os_symbian.h"


#define DEFAULT_MAX_TIMED_OUT_PER_POLL  (64)


/**
 * The implementation of timer heap.
 */
struct pj_timer_heap_t
{
    /** Maximum size of the heap. */
    pj_size_t max_size;

    /** Current size of the heap. */
    pj_size_t cur_size;

    /** Max timed out entries to process per poll. */
    unsigned max_entries_per_poll;
};


//////////////////////////////////////////////////////////////////////////////
/**
 * Active object for each timer entry.
 */
class CPjTimerEntry : public CActive 
{
public:
    static CPjTimerEntry* NewL(	pj_timer_heap_t *timer_heap,
    				pj_timer_entry *entry,
    				const pj_time_val *delay);
    
    ~CPjTimerEntry();
    
    virtual void RunL();
    virtual void DoCancel();

private:	
    pj_timer_heap_t *timer_heap_;
    pj_timer_entry  *entry_;
    RTimer	     rtimer_;
    
    CPjTimerEntry(pj_timer_heap_t *timer_heap, pj_timer_entry *entry);
    void ConstructL(const pj_time_val *delay);
};


CPjTimerEntry::CPjTimerEntry(pj_timer_heap_t *timer_heap,
			     pj_timer_entry *entry)
: CActive(PJ_SYMBIAN_TIMER_PRIORITY), timer_heap_(timer_heap), entry_(entry)
{
}

CPjTimerEntry::~CPjTimerEntry() 
{
    if (IsActive())
	Cancel();
    rtimer_.Close();
}

void CPjTimerEntry::ConstructL(const pj_time_val *delay) 
{
    rtimer_.CreateLocal();
    CActiveScheduler::Add(this);
    
    pj_int32_t interval = PJ_TIME_VAL_MSEC(*delay) * 1000;
    if (interval < 0) {
    	interval = 0;
    }
    rtimer_.After(iStatus, interval);
    SetActive();
}

CPjTimerEntry* CPjTimerEntry::NewL(pj_timer_heap_t *timer_heap,
				   pj_timer_entry *entry,
				   const pj_time_val *delay) 
{
    CPjTimerEntry *self = new CPjTimerEntry(timer_heap, entry);
    CleanupStack::PushL(self);
    self->ConstructL(delay);
    CleanupStack::Pop(self);

    return self;
}

void CPjTimerEntry::RunL() 
{
    --timer_heap_->cur_size;
    entry_->_timer_id = NULL;
    entry_->cb(timer_heap_, entry_);
    
    // Finger's crossed!
    delete this;
}

void CPjTimerEntry::DoCancel() 
{
     rtimer_.Cancel();
}


//////////////////////////////////////////////////////////////////////////////


/*
 * Calculate memory size required to create a timer heap.
 */
PJ_DEF(pj_size_t) pj_timer_heap_mem_size(pj_size_t count)
{
    return /* size of the timer heap itself: */
           sizeof(pj_timer_heap_t) + 
           /* size of each entry: */
           (count+2) * (sizeof(pj_timer_entry*)+sizeof(pj_timer_id_t)) +
           /* lock, pool etc: */
           132;
}

/*
 * Create a new timer heap.
 */
PJ_DEF(pj_status_t) pj_timer_heap_create( pj_pool_t *pool,
					  pj_size_t size,
                                          pj_timer_heap_t **p_heap)
{
    pj_timer_heap_t *ht;

    PJ_ASSERT_RETURN(pool && p_heap, PJ_EINVAL);

    *p_heap = NULL;

    /* Allocate timer heap data structure from the pool */
    ht = PJ_POOL_ALLOC_T(pool, pj_timer_heap_t);
    if (!ht)
        return PJ_ENOMEM;

    /* Initialize timer heap sizes */
    ht->max_size = size;
    ht->cur_size = 0;
    ht->max_entries_per_poll = DEFAULT_MAX_TIMED_OUT_PER_POLL;

    *p_heap = ht;
    return PJ_SUCCESS;
}

PJ_DEF(void) pj_timer_heap_destroy( pj_timer_heap_t *ht )
{
    PJ_UNUSED_ARG(ht);
}

PJ_DEF(void) pj_timer_heap_set_lock(  pj_timer_heap_t *ht,
                                      pj_lock_t *lock,
                                      pj_bool_t auto_del )
{
    PJ_UNUSED_ARG(ht);
    if (auto_del)
    	pj_lock_destroy(lock);
}


PJ_DEF(unsigned) pj_timer_heap_set_max_timed_out_per_poll(pj_timer_heap_t *ht,
                                                          unsigned count )
{
    unsigned old_count = ht->max_entries_per_poll;
    ht->max_entries_per_poll = count;
    return old_count;
}

PJ_DEF(pj_timer_entry*) pj_timer_entry_init( pj_timer_entry *entry,
                                             int id,
                                             void *user_data,
                                             pj_timer_heap_callback *cb )
{
    pj_assert(entry && cb);

    entry->_timer_id = NULL;
    entry->id = id;
    entry->user_data = user_data;
    entry->cb = cb;

    return entry;
}

PJ_DEF(pj_status_t) pj_timer_heap_schedule( pj_timer_heap_t *ht,
					    pj_timer_entry *entry, 
					    const pj_time_val *delay)
{
    CPjTimerEntry *timerObj;
    
    PJ_ASSERT_RETURN(ht && entry && delay, PJ_EINVAL);
    PJ_ASSERT_RETURN(entry->cb != NULL, PJ_EINVAL);

    /* Prevent same entry from being scheduled more than once */
    PJ_ASSERT_RETURN(entry->_timer_id == NULL, PJ_EINVALIDOP);

    timerObj = CPjTimerEntry::NewL(ht, entry, delay);
    entry->_timer_id = (void*) timerObj;
    
    ++ht->cur_size;
    return PJ_SUCCESS;
}

PJ_DEF(int) pj_timer_heap_cancel( pj_timer_heap_t *ht,
				  pj_timer_entry *entry)
{
    PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL);
    
    if (entry->_timer_id != NULL) {
    	CPjTimerEntry *timerObj = (CPjTimerEntry*) entry->_timer_id;
    	timerObj->Cancel();
    	delete timerObj;
    	entry->_timer_id = NULL;
    	--ht->cur_size;
    	return 1;
    } else {
    	return 0;
    }
}

PJ_DEF(unsigned) pj_timer_heap_poll( pj_timer_heap_t *ht, 
                                     pj_time_val *next_delay )
{
    /* Polling is not necessary on Symbian, since all async activities
     * are registered to active scheduler.
     */
    PJ_UNUSED_ARG(ht);
    if (next_delay) {
    	next_delay->sec = 1;
    	next_delay->msec = 0;
    }
    return 0;
}

PJ_DEF(pj_size_t) pj_timer_heap_count( pj_timer_heap_t *ht )
{
    PJ_ASSERT_RETURN(ht, 0);

    return ht->cur_size;
}

PJ_DEF(pj_status_t) pj_timer_heap_earliest_time( pj_timer_heap_t * ht,
					         pj_time_val *timeval)
{
    /* We don't support this! */
    PJ_UNUSED_ARG(ht);
    
    timeval->sec = 1;
    timeval->msec = 0;
    
    return PJ_SUCCESS;
}

