/*
 * psupdaterengine.h
 *
 * Copyright (C) 2001 Atomic Blue (info@planeshift.it, http://www.atomicblue.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 (version 2 of the License)
 * 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.
 *
 */
#ifndef __ENGINE_H__
#define __ENGINE_H__

#include <csutil/sysfunc.h>
#include <csutil/csstring.h>
#include <csutil/ref.h>
#include <csutil/thread.h>

#include "updater.h"
#include "util/genericevent.h"

using updater::Updater;

struct iObjectRegistry;
struct iGraphics3D;
struct iGraphics2D;
struct iTextureManager;
struct iFont;
struct iEngine;
struct iLoader;
struct iVFS;
struct iEvent;
struct iEventQueue;
struct iConfigManager;
struct iVirtualClock;
struct iConfigManager;

class pawsMainWidget;
class PawsManager;


class psUpdaterEngine
{
public:

    psUpdaterEngine (iObjectRegistry *object_reg, bool silent);

    virtual ~psUpdaterEngine ();

    bool InitializeCS();
    bool Initialize ();
    void QuitClient();

    void SetupFrame();
    void FinishFrame();

    bool IsSilent() {return silentMode;}

    void InstallDirectory(const char* path,const char* to);

    bool HandleEvent (iEvent &Event);

    iObjectRegistry*    GetObjectRegistry(){ return object_reg; }
    iEngine*            GetEngine(){ return engine; }
    iGraphics3D*        GetG3D(){ return graphics3d; }
    iGraphics2D*        GetG2D(){ return graphics2d; }
    iVFS*               GetVFS(){ return vfs; }
    iConfigManager*     GetConfig() { return cfgmgr; }
    pawsMainWidget*     GetMainWidget() { return mainWidget; }
    iEvent*             GetLastEvent() { return lastEvent; }
    Updater*            GetUpdater(){ return update; }
    iConfigManager*     GetConfigManager(){ return configMgr; }
    iDocumentSystem*    GetDocumentSystem() {return xmlSystem;}

    /// Declare our event handler
    DeclareGenericEventHandler(EventHandler,psUpdaterEngine,"planeshift.updater");
    csRef<EventHandler> scfiEventHandler;

    void    LoadWidgets();

    void    OutToScreen(const char* format,...);
    void    OutToScreen(int color,const char* format,...);

    // Be very careful with these! Deadlock possible!
    void    LockStatusMutex() { status_mutex->LockWait(); }
    void    UnlockStatusMutex() { status_mutex->Release(); }

    bool GetCreateMode() { return createMode; }
    void SetCreateMode() { createMode = true; }

    bool CanUpdate() { return canUpdate;}

    void CriticalError(const char* format,...);

    bool LaunchProgram(const char* path,const char* in);

    // This function copies all the files in a folder to the "to" path (ONLY USED IN AUTOUPDATING)
    void Install(const char* to);

    int FindRGB(int r,int g, int b);
private:

    iObjectRegistry*        object_reg;
    csRef<iEngine>        engine;
    csRef<iConfigManager>   cfgmgr;
    csRef<iTextureManager>  txtmgr;
    csRef<iVFS>                vfs;
    csRef<iGraphics2D>        graphics2d;
    csRef<iGraphics3D>        graphics3d;
    csRef<iEventQueue>        queue;
    csRef<iConfigManager>   configMgr;
    csRef<iVirtualClock>    vc;
    csRef<iDocumentSystem>  xmlSystem;

    csRef<Updater> update;
    csRef<csMutex> status_mutex;

    // Used to stop rendering when the window is minimized
    bool drawScreen;

    // Paws
    PawsManager*    paws;
    pawsMainWidget* mainWidget;
    
    void    RegisterFactories();

    // Used to store the last event
    iEvent* lastEvent;

    bool silentMode;
    bool createMode;
    // This will be set if the everthing went OK
    bool canUpdate;

    /// Limits the frame rate either by sleeping
    void FrameLimit();

    /// Time elapsed since the last drawn frame.
    csTicks elapsed;

};

#endif
