/* $Id$ */
/* 
 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 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;
}

