/***************************************************************************
*   Copyright (C) 2004 by Messenger of death                              *
*   riper@fromru.com                                                      *
*                                                                         *
*   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.             *
***************************************************************************/
#ifndef ME_N_VIDEOME_C_OPENGL_VIDEO_DRIVER_H
#define ME_N_VIDEOME_C_OPENGL_VIDEO_DRIVER_H
#include <me_defines.h>
#include <me_c_video_driver_interface.h>


namespace ME_n_Video
{
	/**
	Видео драйвер для работы с библотекой OpenGL.
	Создание окна производится с помощью библиотеки SDL.
	 
	@author Denis A. Birukov aka Messenger of death 
	*/
	class ME_c_OpenGL_Video_Driver : public ME_c_Video_Driver_Interface
	{
		public:
			ME_c_OpenGL_Video_Driver();

			~ME_c_OpenGL_Video_Driver();

			/**
			Производит отображение одной поверхности на другую.
			Вслучае шибки бросается исключение, если rise_exception==true
			*/
			bool _blit(  ME_c_Video_Surface& from, Sint16 x,Sint16 y,bool rise_exception=true );
			bool _blit(  ME_c_Video_Surface& from, double x,double y,bool rise_exception=true );
			/**
			Производит отображение одной поверхности на другую.
			Вслучае шибки бросается исключение, если rise_exception==true
			*/
			
			 bool _blit( const std::string &from,Sint16 x,Sint16 y ,bool rise_exception=true );
			 bool _blit( const std::string &from,double x,double y ,bool rise_exception=true );
			/**
			Удаляет выделенную поверхность
			*/
			bool _free_surface( ME_c_Video_Surface* surf );
			/**
			Удаляет выделенную поверхность
			*/
			 bool _free_surface( std::string name );
			/**
			Удаляет выделенную поверхность
			*/
			 bool _free_surface( std::string group,std::string name ) ;
			/**
			Инициализация драйвера
			*/
			bool _init();
			/**
			Деинициализация драйвера
			*/
			void _deinit();
			/**
			Изменяет текущую группу
			*/
			bool _set_group( std::string name );
			/**
			Возвращает ссылку на поверхность в указанной группе с указанным именем.
			*/
			/**
			Возвращает имя драйвера
			*/
			const std::string _get_driver_name();
			/**
			Создание поверхности в текущей группе.
			Возвращает ссылку на поверхность.
			В случае еси поверхность существует - она будет перетерта
			*/
			ME_c_Video_Surface& _create_surface( Sint16 xs, Sint16 ys );
			ME_c_Video_Surface& _create_surface( double xs, double ys );
			/**
			Создание поверхности в текущей группе с заданным именем.
			Если имя уже существует, то старая поверхность будет удалена, если rewrite==true
			Иначе будет выброшено исключение и возвращена ссылка на существующую поверхность.
			Возвращает ссылку на поверхность.
			*/
			ME_c_Video_Surface& _create_surface( Sint16 xs, Sint16 ys, std::string name, bool rewrite, bool rise_exception );
			ME_c_Video_Surface& _create_surface( double xs,double ys, std::string name, bool rewrite, bool rise_exception );
			/**
			Создание поверхности в указанной группе с заданным именем.
			Если имя уже существует, то старая поверхность будет удалена, если rewrite==true.
			Иначе будет возвращена старая поверхность(если rise_exception==false). В случае если rise_exception=true будет брошено исклдчение.
			Если указанная группа несуществует, то она будет создана
			Возвращает ссылку на поверхность.
			*/
			ME_c_Video_Surface& _create_surface( Sint16 xs, Sint16 ys, std::string name, bool rewrite, std::string group_name,bool rise_exception=true );
			ME_c_Video_Surface& _create_surface( double xs, double ys, std::string name, bool rewrite, std::string group_name,bool rise_exception=true );
			/**
			Возвращает ссылку на поверхность в указанной группе с указанным именем.
			*/
			ME_c_Video_Surface& _get_surface( std::string grp, std::string name );
			/**
			Добавляет поверхность в текущею группу. Имя дается случайно. возвращает имя.
			*/
			std::string _insert_surface( ME_c_Video_Surface* surf );
			/**
			Добавляет поверхность в текущею группу и дает ей указанное имя.
			Если имя уже существует и rewrite !=0 то будет вызвано исключение, а функция вернет ссылку на текущую поверхность с таким именем.
			Возвращает ссылку на поверхность.
			*/
			ME_c_Video_Surface& _insert_surface( ME_c_Video_Surface* surf, std::string name, bool rewrite,bool rise_exception=true );
			/**
			Добавляет поверхность в заданную группу и дает ей указанное имя.
			Если имя уже существует и rewrite !=0 то будет вызвано исключение, а функция вернет ссылку на текущую поверхность с таким именем.
			Если указанная группа несуществует, то она будет создана.
			Возвращает ссылку на поверхность.
			*/
			ME_c_Video_Surface& _insert_surface( ME_c_Video_Surface* surf, std::string name, bool rewrite, std::string grp,bool rise_exception=true );
			/**
			Возвращает ссылку на поверхность. Поиск производится внутри текущей группы*/
			ME_c_Video_Surface& operator [ ] ( std::string name );
			/**
			Изменяет текущую группу.
			В случае если такая группа несуществует, будет выброшено исключение.
			*/
			ME_c_Video_Driver_Interface& operator() ( std::string name );
			/**
			Создает поверхность с указанными размерами. Глубина цвета поверхности совпадает с глубиной цвета основной экранной поверхности.
			Возвращает имя поверхности. Предпочтительней использовать данную версию функции.
			Поверхность создается в группе по умолчанию
			*/
 			std::string _allocate_surface( Sint16 xs, Sint16 ys );
 			std::string _allocate_surface( double xs, double ys );
			/** Возвращает основную поверхность*/
			ME_c_Video_Surface& _get_main_surface();
			/** Возвращает информацию о поддерживаемых возможностях*/
			const ME_c_Video_Features& _get_features();
			/** Производит отображение отрисованых элементов*/
			void _draw();
		private:
			friend class ME_c_OpenGL_Video_Surface;
			Sint16 _w_;
			Sint16 _h_;
			Uint8 _bpp_;
			Uint16 _RSize_;
			Uint16 _GSize_;
			Uint16 _BSize_;
			Uint16 _ASize_;
			Uint8 _depth_;
			std::string _driver_name_;
			std::string _cur_group_;
			std::map<std::string, std::map<std::string, ME_c_Video_Surface*>* > _surfaces_;
	};
	extern "C" DECLSPEC ME_c_Video_Driver_Interface* _create_video_driver();
}

#endif
