/*
  libuta - a C++ widget library based on SDL (Simple Direct Layer)
  Copyright (C) 1999-2002  Karsten Laux

  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., 59 Temple Place - Suite 330,
  Boston, MA  02111-1307, SA.
*/
// written by Karsten Laux, June 1999  

#ifndef _PIXELFORMAT_H_
#define _PIXELFORMAT_H_

#include "color.h"
#include "point.h"


//just for typedefs ...
#include <SDL/SDL.h>

#include <string>
#include <vector>

namespace uta {

/**Format of pixels in memory.
   The format RGB0888 means that the display runs at 24bpp, but the
   pixel values are 4-byte-aligned in memory for faster access on a 
   32bit system (Matrox cards do this).
*/ 
class Pixelformat
{
 public:
  ///
  enum {DISPLAY , ABGR8888, RGBA8888, ARGB8888, BGRA8888, RGB888, 
	BGR888, RGB0888, BGR0888, RGB565, RGB555, IND8, UNKNOWN};
  ///
  Pixelformat() : format_(UNKNOWN), bytesPerPixel_(0) {};
  ///
  Pixelformat(const Pixelformat& other) 
    { init(other.format_); palette = other.palette; };
  ///
  Pixelformat(int);
  ///
  ~Pixelformat() {};
  ///
  std::string asString() const;
  ///
  int operator() () const {return format_;};
  ///
  operator int() const { return format_;};
  ///
  bool operator ==(int a) const { return format_ == a; };
  ///
  bool operator ==(const Pixelformat& other) const
  { return other.format_ == format_ && other.palette == palette; };
  ///
  std::vector<Color> palette;
  ///
  Uint32 mapToPixel(const Color& col) const;
  ///
  Color mapToColor(Uint32 pixel) const;
  ///
  bool valid() const { return valid_; };

  ///
  int bpp() const { return bytesPerPixel_; }
  ///
  Uint32 rMask() const { return rmask_;};
  ///
  Uint32 gMask() const { return gmask_;};
  ///
  Uint32 bMask() const { return bmask_;};
  ///
  Uint32 aMask() const { return amask_;};
  
  ///
  static Pixelformat displayFormat;
  ///
  static int identify(Uint8 bpp, 
		     Uint32 rmask, Uint32 gmask, Uint32 bmask, Uint32 amask);
 private:

  ///
  int getShift(Uint32) const;
  ///
  int getLoss(Uint32) const;
  ///
  void init(int);
  ///
  static const char* names[];
  ///RGBA bitmasks
  static Uint32 masks[][4];
  
  static int bytes[];

  ///
  int format_;
  ///
  int bytesPerPixel_;
  ///
  Uint32 rmask_;
  ///
  int rshift_;
  ///
  int rloss_;
  ///
  Uint32 gmask_;
  ///
  int gshift_;
  ///
  int gloss_;
  ///
  Uint32 bmask_;
  ///
  int bshift_;
  ///
  int bloss_;
  ///
  Uint32 amask_;
  ///
  int ashift_;
  ///
  int aloss_;
  ///
  bool valid_;
};

}


#endif
