/*
 * This file is part of libtqtvd_astronav
 *
 * Copyright (C) 2008-2017 TQTVD Software
 * Copyright (C) 2017 Mirakulo Software (mirakulo@mirakulo.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301  USA
 */

#ifndef IAstroNavPlayer_h
#define IAstroNavPlayer_h

#include "IGraphicManagerAdapter.h"
#include <string>

#include <TQTVD_common.h>

#define DLLEXPORT __attribute__ ((visibility("default")))

using namespace TQTVD::GraphicManager;

#define XHTMLPLAYER_GETFACTORY       "getPlayerFactory"
#define XHTMLPLAYER_SETADAPTER       "setGraphicManagerAdapter"
#define XHTMLPLAYER_ADDFILESERVER    "addFileServer"
#define XHTMLPLAYER_REMOVEFILESERVER "removeFileServer"


namespace AstroNav {

	class IAstroNavPlayerFactory;

	typedef unsigned RGBA32;        // RGBA quadruplet
	typedef IAstroNavPlayerFactory* (*getFactory_t) (void);


	DECLARE_SHARE_PTR(IAstroNavPlayerFileServer);

	class IAstroNavPlayerFileServer {

	   public:

		  virtual ~IAstroNavPlayerFileServer() {}
		  virtual unsigned long open(std::string path, bool readWrite = false) = 0;
		  virtual void close(unsigned long fd) = 0;
		  virtual unsigned long read(unsigned long fd, unsigned char* buff, unsigned long len, bool blocking = false) = 0;
		  virtual unsigned long write(unsigned long fd, unsigned char* buff,  unsigned long  len, bool blocking = false) = 0;
		  virtual unsigned long size(std::string path)  = 0;
		  virtual unsigned long size(unsigned long fd )  = 0;
		  virtual unsigned long setFilePos(unsigned long fd, unsigned long pos) = 0;
	};

	class AstroNavPlayerFileServerWrapper {
		private:
			IAstroNavPlayerFileServerWPtr m_fileserver;
		public:
			AstroNavPlayerFileServerWrapper(IAstroNavPlayerFileServerWPtr fileserver) : m_fileserver(fileserver) {}		  
			virtual ~AstroNavPlayerFileServerWrapper() {}

			IAstroNavPlayerFileServerWPtr fileserver() { return m_fileserver; }
	};
			

	DECLARE_SHARE_PTR(IAstroNavPlayerUpdateListener);

	class IAstroNavPlayerUpdateListener {
	   public:

		  virtual ~IAstroNavPlayerUpdateListener() {}
		  virtual void updateCb(IGraphicManagerAdapterSurface *surface, int x0, int y0, int width, int height) = 0;

	};

	DECLARE_SHARE_PTR(IAstroNavPlayerCoreServiceProvider);

    class IAstroNavPlayerCoreServiceProvider {
    public:
        virtual ~IAstroNavPlayerCoreServiceProvider() {}
        virtual timeval getUTCTime() = 0;

        virtual std::string getProperty(std::string prop) = 0;
        virtual bool setProperty(std::string prop, std::string val) = 0;
    };

    struct IAstroNavPlayerArgs { 
        IGraphicManagerAdapterSurface * dest;
        std::string url;
        int x0; int y0; int w; int h;
        std::string css;

        IAstroNavPlayerArgs(IGraphicManagerAdapterSurface * dest, std::string url, 
                            int x0, int y0, int w, int h, std::string css = "")
            : dest(dest)
            , url(url)
            , x0(x0)
            , y0(y0)
            , w(w)
            , h(h)
            , css(css)
        {
        }
    };

    DECLARE_SHARE_PTR(IAstroNavPlayer)

	class IAstroNavPlayer {

		public:

			typedef enum Status_e	{ STATE_NOT_READY, STATE_READY, STATE_PLAYING, STATE_UNLOAD }	Status ;

			enum MouseButton { NoButton = -1, LeftButton, MiddleButton, RightButton };
			enum MouseEventType { MouseEventMoved, MouseEventPressed, MouseEventReleased, MouseEventScroll };

	 		virtual ~IAstroNavPlayer() {}

			virtual void play(IGraphicManagerAdapterSurface *dest, std::string url, int x0, int y0, int w, int h,
                                std::string css = "") = 0;
			virtual void stop (void) = 0;
			virtual void unload (void) = 0;
			virtual void setFocus(void) = 0;
			virtual bool hasFocus(void) = 0;
			virtual void setBackgroundColor(RGBA32 color) = 0;
			virtual RGBA32 getBackgroundColor(void) = 0;
			virtual void rcEventReceived (int aKeyCode) = 0;
			virtual void kbEventReceived ( int aKeyCode,  bool bShiftKey, bool bCtrlKey, bool bAltKey, bool bMetaKey) = 0;
            virtual void setRect(int x, int y, int w, int h) = 0;
			virtual void mouseEventReceived (
				MouseButton mouseButton, MouseEventType type, int x, int y) = 0;

			virtual void back() = 0;
			virtual void forward() = 0;
			virtual void setURL(std::string url, std::string css) = 0;
			virtual void reload() = 0;
			virtual void cancel() = 0;

			virtual AstroNavPlayerFileServerWrapper *fileServerWrapper() const = 0;
			virtual IAstroNavPlayerCoreServiceProviderWPtr coreServices() = 0;

            typedef void (*wait_func_t)(void);
			virtual wait_func_t getWaitFunc() = 0; 

        protected:
            virtual void play_(IAstroNavPlayerArgs * args) = 0;
			virtual void stop_(void) = 0;
	};

        class IAstroNavPlayerFactory  {

          public:

            virtual ~IAstroNavPlayerFactory() {}
            virtual IAstroNavPlayerPtr reservePlayer( IGraphicManagerAdapter * gm
                                                  , IAstroNavPlayerUpdateListenerPtr listener
                                                  , IAstroNavPlayerFileServerPtr fileServer
                                                  , IAstroNavPlayerCoreServiceProviderPtr coreServices ) = 0;
            virtual void releasePlayer(IAstroNavPlayerPtr& player) = 0;

        };


}

#endif

