#ifndef GRAPHIC_H_
#define GRAPHIC_H_

extern Font* font_hankaku;

namespace system {
	/*
	 * 描画インターフェースクラス
	 * 描画メソッド集
	 */
	class IDraw {
	protected:
		int xsize_, ysize_;
	public:
		int get_xsize() const { return xsize_; }
		int get_ysize() const { return ysize_; }


		/*
		 * 純粋仮想関数
		 * それぞれのクラスで実装しなければいけない
		 */
		virtual void point(int x, int y, color_16 color) = 0;
		virtual color_16 get_color(int x, int y) const = 0;

		// 純粋ではない仮想関数
		virtual void line(int x0, int y0, int x1, int y1, color_16 color);
		/*
		 * 四角く塗りつぶす
		 * x1, y1も範囲に含まれるので注意
		 */
		virtual void box(int x0, int y0, int x1, int y1, color_16 color);
		virtual void putchar(int x, int y, byte c, color_16 color,
			Font* font = font_hankaku);
		virtual void putchar_expand(int x, int y, byte c, color_16 color,
			dword expand, Font* font = font_hankaku);
		virtual void putstr(int x, int y, const char* str, color_16 color,
			Font* font = font_hankaku);
		virtual void putstr_expand(int x, int y, const char* str, color_16 color,
			dword expand, Font* font = font_hankaku);
		virtual void putpict(int xpos, int ypos, const IDraw& pict,
			int x0 = 0, int y0 = 0, int x1 = -1, int y1 = -1);
	};
	
	/*
	 * 画面クラス
	 */
	class Screen : public IDraw {
		driver::IVideo* vdrv_; // ビデオドライバへのポインタ
	public:
		static const color_16 BACKGROUND_COLOR = 0x3ab2;
		static const color_16 TASKBAR_COLOR = 0xe73c;
		explicit Screen(driver::IVideo* video_driver, int xsize, int ysize);
		void point(int x, int y, color_16 color);
		color_16 get_color(int x, int y) const;
	};
	
	/*
	 * 画像クラス
	 */
	class Picture : public IDraw {
		color_16* buffer_;
		
	private:
		// デフォルトコンストラクタを禁止
	public:
		explicit Picture();
		explicit Picture(int xsize, int ysize);
		
		// コピーコンストラクタ
		explicit Picture(const Picture& pict);
		
		virtual ~Picture();
		
		void init(int xsize, int ysize);
		void point(int x, int y, color_16 color);
		color_16 get_color(int x, int y) const;
	};
	
	
	void init_palette();
	void set_palette(int start, int end, byte *rgb);

	inline color_16 convC(color_32 color);
	inline color_32 convC_inv(color_16 color);
	color_16 mixC(color_32 color1, color_32 color2, int color1_ratio, int color2_ratio);

}

color_16 system::convC(color_32 color)
{
	// 24bit color → 16bit color
	return ((color >> 8) & 0xf800) | ((color >> 5) & 0x07e0) | ((color >> 3) & 0x001f);
}

color_32 system::convC_inv(color_16 color)
{
	// 16bit color → 24bit color
	return ((color & 0xf800) << 8) | ((color & 0x07e0) << 5) | ((color & 0x001f) << 3);
}

#endif /*GRAPHIC_H_*/
