/* $Id$ */
/* 
 * Copyright (C)2003-2006 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/sock_select.h>
#include <pj/array.h>
#include <pj/assert.h>
#include <pj/os.h>
#include "os_symbian.h"

 
struct symbian_fd_set
{
    unsigned	 count;
    CPjSocket	*sock[PJ_IOQUEUE_MAX_HANDLES];
};


PJ_DEF(void) PJ_FD_ZERO(pj_fd_set_t *fdsetp)
{
    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
    fds->count = 0;
}


PJ_DEF(void) PJ_FD_SET(pj_sock_t fd, pj_fd_set_t *fdsetp)
{
    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;

    PJ_ASSERT_ON_FAIL(fds->count < PJ_IOQUEUE_MAX_HANDLES, return);
    fds->sock[fds->count++] = (CPjSocket*)fd;
}


PJ_DEF(void) PJ_FD_CLR(pj_sock_t fd, pj_fd_set_t *fdsetp)
{
    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
    unsigned i;
    
    for (i=0; i<fds->count; ++i) {
	if (fds->sock[i] == (CPjSocket*)fd) {
	    pj_array_erase(fds->sock, sizeof(fds->sock[0]), fds->count, i);
	    --fds->count;
	    return;
	}
    }
}


PJ_DEF(pj_bool_t) PJ_FD_ISSET(pj_sock_t fd, const pj_fd_set_t *fdsetp)
{
    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
    unsigned i;
    
    for (i=0; i<fds->count; ++i) {
	if (fds->sock[i] == (CPjSocket*)fd) {
	    return PJ_TRUE;
	}
    }

    return PJ_FALSE;
}

PJ_DEF(pj_size_t) PJ_FD_COUNT(const pj_fd_set_t *fdsetp)
{
    symbian_fd_set *fds = (symbian_fd_set *)fdsetp;
    return fds->count;
}


PJ_DEF(int) pj_sock_select( int n, 
			    pj_fd_set_t *readfds, 
			    pj_fd_set_t *writefds,
			    pj_fd_set_t *exceptfds, 
			    const pj_time_val *timeout)
{
    CPjTimeoutTimer *pjTimer;
    unsigned i;

    PJ_UNUSED_ARG(n);
    PJ_UNUSED_ARG(writefds);
    PJ_UNUSED_ARG(exceptfds);

    if (timeout) {
	pjTimer = PjSymbianOS::Instance()->SelectTimeoutTimer();
	pjTimer->StartTimer(timeout->sec*1000 + timeout->msec);

    } else {
	pjTimer = NULL;
    }

    /* Scan for readable sockets */

    if (readfds) {
	symbian_fd_set *fds = (symbian_fd_set *)readfds;

	do {
	    /* Scan sockets for readily available data */
	    for (i=0; i<fds->count; ++i) {
		CPjSocket *pjsock = fds->sock[i];

		if (pjsock->Reader()) {
		    if (pjsock->Reader()->HasData() && !pjsock->Reader()->IsActive()) {

			/* Found socket with data ready */
			PJ_FD_ZERO(readfds);
			PJ_FD_SET((pj_sock_t)pjsock, readfds);

			/* Cancel timer, if any */
			if (pjTimer) {
			    pjTimer->Cancel();
			}

			/* Clear writable and exception fd_set */
			if (writefds)
			    PJ_FD_ZERO(writefds);
			if (exceptfds)
			    PJ_FD_ZERO(exceptfds);

			return 1;

		    } else if (!pjsock->Reader()->IsActive())
			pjsock->Reader()->StartRecvFrom();

		} else {
		    pjsock->CreateReader();
		    pjsock->Reader()->StartRecvFrom();
		}
	    }

	    PjSymbianOS::Instance()->WaitForActiveObjects();

	} while (pjTimer==NULL || !pjTimer->HasTimedOut());
    }


    /* Timeout */

    if (readfds)
	PJ_FD_ZERO(readfds);
    if (writefds)
	PJ_FD_ZERO(writefds);
    if (exceptfds)
	PJ_FD_ZERO(exceptfds);

    return 0;
}

