/*
 * Copyright (C) 1997-2009, R3vis Corporation.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
 *
 * Original Contributor:
 *   Wes Bethel, R3vis Corporation, Marin County, California
 *   http://www.r3vis.com/
 * Additional Contributor(s):
 *
 * The OpenRM project is located at http://openrm.sourceforge.net/.
 */
/*
 * $Id: rminit.c,v 1.9 2008/09/21 12:54:23 wes Exp $
 * Version: $Name: v180-alpha-02 $
 * $Revision: 1.9 $
 * $Log: rminit.c,v $
 * Revision 1.9  2008/09/21 12:54:23  wes
 * Scene graph consistency stuff
 *
 * Revision 1.8  2006/11/19 17:16:33  wes
 * Update to accommodate new second bool argument to rmSubtreeDelete
 *
 * Revision 1.7  2005/03/19 17:17:19  wes
 * Win32 clock init stuff, and deinit upon rmFinish (in response to report
 * of 8-byte memory leak).
 *
 * Revision 1.6  2005/02/19 16:41:34  wes
 * Distro sync and consolidation.
 * Support for NO_PTHREADS build.
 *
 * Revision 1.5  2005/01/23 17:04:03  wes
 * Copyright update to 2005.
 *
 * Revision 1.4  2004/03/30 14:13:31  wes
 * Fixed declarations and man page docs for several routines.
 *
 * Revision 1.3  2004/01/16 16:45:12  wes
 * Updated copyright line for 2004.
 *
 * Revision 1.2  2003/02/02 02:07:15  wes
 * Updated copyright to 2003.
 *
 * Revision 1.1.1.1  2003/01/28 02:15:23  wes
 * Manual rebuild of rm150 repository.
 *
 * Revision 1.10  2003/01/16 22:21:17  wes
 * Updated all source files to reflect new organization of header files:
 * all header files formerly located in include/rmaux, include/rmi, include/rmv
 * are now located in include/rm.
 *
 * Revision 1.9  2002/09/17 14:15:52  wes
 * Added conditional call to rmComponentManagerPrintStatus() inside rmFinish.
 * Set the DEBUG_FINAL_MEMCHECK bit on DEBUG_LEVEL to compile this call in
 * so that applications will see if there are any app-induced memory leaks
 * at finish time.
 *
 * Revision 1.8  2002/08/29 22:20:32  wes
 *
 * Massive upgrade to accommodate dynamic object reallocation within
 * the component manager, and within the context cache. Use the
 * debug #define DEBUG_LEVEL DEBUG_REALLOC_TRACE to get a printf
 * whenever a realloc occurs. With this upgrade, there are no
 * OpenRM limits on the size of the scene graph. There will be external
 * limits, such as the amount of RAM and the amount of space available
 * to your OpenGL implementation.
 *
 * Revision 1.7  2002/08/19 00:54:27  wes
 * Added API entries for new experiemental routines to get and set
 * the size of the OpenRM component manager object pool.
 *
 * Revision 1.6  2002/08/17 15:10:11  wes
 * Added the routine rmInitComponentPoolSize(). This routine can be called
 * before (and only before) rmInit() to adjust the size of the
 * component manager's object pool.
 *
 * Revision 1.5  2002/04/30 19:31:59  wes
 * Updated copyright dates.
 *
 * Revision 1.4  2001/07/15 17:16:25  wes
 * Removed dead code.
 *
 * Revision 1.3  2001/06/03 20:46:36  wes
 * Removed unused vars to clean up compile warnings.
 *
 * Revision 1.2  2001/03/31 17:12:38  wes
 * v1.4.0-alpha-2 checkin.
 *
 * Revision 1.1  2000/12/03 22:33:06  wes
 * Initial entry.
 *
 */

#include <rm/rm.h>
#include "rmprivat.h"

/*
 * ----------------------------------------------------
 * @Name rmInit
 @pstart
 void rmInit (void)
 @pend

 @astart
 No arguments.
 @aend

 @dstart

 An initialization routine, rmInit() will perform 4 steps:

   1) initialize the internal scene graph datastructure
   2) precompute trigonometric values used for primitive tessellation
   3) initialize the internal font registry datastructure
   4) output the OpenRM copyright notice

 After these steps are performed, RM is not yet fully functional,
 since a rendering context must be created, bound to an RMpipe, and
 that context made current in order for rendering to proceed.

 See rmauxCreateXWindow, rmauxCreateW32Window, rmPipeSetWindow,
 rmPipeMakeCurrent.

 @dend
 * ----------------------------------------------------
 */
void
rmInit (void)
{
    extern RMcompMgrHdr *global_RMimagePool, *global_RMprimitivePool;
    extern RMcompMgrHdr *global_RMnodePool, *global_RMtexturePool;
    extern RMcompMgrHdr *global_RMtextPropsPool;

#ifdef RM_X

  /*stat = XInitThreads();   */

#ifdef SOLARIS
    glXInitThreadsSUN();
#else

#ifndef _NO_PTHREADS
    pthread_setconcurrency(12);
#endif
    
#endif
#endif

#ifdef RM_WIN
    private_initTimer();
#endif

    /*
     * Initialize the component manager, which manages RMimages,
     * RMprimitives, RMnodes, RMtextures and RMtextProps.
     */
    if ((global_RMimagePool = private_rmInitComponentManager(NUM_ITEMS_PER_PAGE,sizeof(RMimage))) == NULL)
    {
	rmError("rmInit() Fatal error: unable to alloc object pool for RMimage objects.");
	exit(-1);
    }
	
    if ((global_RMprimitivePool = private_rmInitComponentManager(NUM_ITEMS_PER_PAGE,sizeof(RMprimitive))) == NULL)
    {
	rmError("rmInit() Fatal error: unable to alloc object pool for RMprimitive objects.");
	exit(-1);
    }
	
    if ((global_RMnodePool = private_rmInitComponentManager(NUM_ITEMS_PER_PAGE,sizeof(RMnode))) == NULL)
    {
	rmError("rmInit() Fatal error: unable to alloc object pool for RMnode objects.");
	exit(-1);
    }
	
    if ((global_RMtexturePool = private_rmInitComponentManager(NUM_ITEMS_PER_PAGE,sizeof(RMtexture))) == NULL)
    {
	rmError("rmInit() Fatal error: unable to alloc object pool for RMtexture objects.");
	exit(-1);
    }
    if ((global_RMtextPropsPool = private_rmInitComponentManager(NUM_ITEMS_PER_PAGE,sizeof(RMtextProps))) == NULL)
    {
	rmError("rmInit() Fatal error: unable to alloc object pool for RMtextProps objects.");
	exit(-1);
    }
	
    private_rmInitCacheKeyMutex();
    
    private_initObjectTree();
    private_initTrigTables();

    {
	extern int RM_DEFAULT_DATA_SYNC_NTHREADS;
	rmDataSyncSetNthreads(RM_DEFAULT_DATA_SYNC_NTHREADS);
    }
    
    private_rmHello();
}


/*
 * ----------------------------------------------------
 * @Name rmFinish
 @pstart
 void rmFinish (void)
 @pend

 @astart
 No arguments.
 @aend

 @dstart

 rmFinish() is used to cleanse the OpenRM component manager, and is
 typically called as part of an application's shutdown procedure. It
 will also delete the scene graph rooted at rmRootNode(), but will not
 delete scene graph nodes that are not part of the directed acyclic
 graph connected to rmRootNode().

 @dend
 * ----------------------------------------------------
 */
void
rmFinish (void)
{
    extern RMcompMgrHdr *global_RMimagePool, *global_RMprimitivePool;
    extern RMcompMgrHdr *global_RMnodePool, *global_RMtexturePool;
    extern RMcompMgrHdr *global_RMtextPropsPool;
    
#ifdef RM_WIN
    private_deInitTimer();
#endif
    
    /* grab the root node and do a recursive free */
    rmSubTreeDelete(rmRootNode(), RM_TRUE);

#if (DEBUG_LEVEL & DEBUG_FINAL_MEMCHECK)
    rmComponentManagerPrintStatus();
#endif
	
    private_rmDeleteComponentManager(global_RMimagePool);
    private_rmDeleteComponentManager(global_RMprimitivePool);
    private_rmDeleteComponentManager(global_RMnodePool);
    private_rmDeleteComponentManager(global_RMtexturePool);
    private_rmDeleteComponentManager(global_RMtextPropsPool);
    
    private_rmDestroyCacheKeyMutex();
}
/* EOF */

