(***********************************************************************)
(*                                                                     *)
(*                           Objective Caml                            *)
(*                                                                     *)
(*            François Pessaux, projet Cristal, INRIA Rocquencourt     *)
(*            Pierre Weis, projet Cristal, INRIA Rocquencourt          *)
(*            Jun Furuse, projet Cristal, INRIA Rocquencourt           *)
(*                                                                     *)
(*  Copyright 1999,2000,2001,2002,2001,2002                            *)
(*  Institut National de Recherche en Informatique et en Automatique.  *)
(*  Distributed only by permission.                                    *)
(*                                                                     *)
(***********************************************************************)
open Color
open Bitmap

type elt = int

type t = {
    width: int;
    height: int;
    colormap: Color.map; (* should not be mutable *)
    mutable transparent: int;
    mutable infos: Info.info list;
    data: Bitmap.t
  } 

let create_with width height cmap transparent init_buffer =
  { width= width;
    height= height;
    colormap= cmap;
    transparent= transparent;
    infos= [];
    data= Bitmap.create_with 2 width height init_buffer }
;;

let create width height =
  { width= width;
    height= height;
    colormap= {map= [||]; max= 256 * 256};
    transparent= (-1);
    infos= [];
    data= Bitmap.create 2 width height None }
;;

let make width height init =
  let init = 
    let s = String.create 2 in
    s.[0] <- char_of_int (init / 256);
    s.[1] <- char_of_int (init mod 256);
    Some s
  in
  { width= width;
    height= height;
    colormap= {map= [||]; max= 256 * 256};
    transparent= (-1);
    infos= [];
    data= Bitmap.create 2 width height init }
;;

(* access method *)
let unsafe_get t x y =
  let str, pos = t.data.access x y in 
  int_of_char str.[pos    ] * 256 +
  int_of_char str.[pos + 1] 
;;

let unsafe_set t x y c =
  let str, pos = t.data.access x y in 
  str.[pos    ] <- char_of_int (c / 256);
  str.[pos + 1] <- char_of_int (c mod 256)
;;

let get t x y = 
  Region.check t.width t.height x y;
  unsafe_get t x y
;;

let set t x y c =
  Region.check t.width t.height x y;
  unsafe_set t x y c
;;

let unsafe_get_rgb t x y =
  t.colormap.map.( unsafe_get t x y )
;;

let get_rgb t x y =
  t.colormap.map.( get t x y )
;;

let set_colormap t map =
  t.colormap.max <- map.max;
  t.colormap.map <- map.map

let destroy t =
  Bitmap.destroy t.data
;;

let sub src x y w h =
  { width= w;
    height= h;
    colormap= Color.copy src.colormap;
    transparent= src.transparent;
    infos= [];
    data= Bitmap.sub src.data x y w h }
;;

let blit src sx sy dst dx dy w h =
  Bitmap.blit src.data sx sy dst.data dx dy w h
;;

let to_rgb24 t =
  let rgb24 = Rgb24.create t.width t.height in
  for y = 0 to t.height - 1 do
    for x = 0 to t.width - 1 do
      Rgb24.unsafe_set rgb24 x y (unsafe_get_rgb t x y)
    done
  done;
  rgb24

let to_rgba32 t =
  let rgba32 = Rgba32.create t.width t.height in
  for y = 0 to t.height - 1 do
    for x = 0 to t.width - 1 do
      Rgba32.unsafe_set rgba32 x y 
	(let index = unsafe_get t x y in
	 { color= t.colormap.map.(index);
	   alpha= if index = t.transparent then 0 else 255 })
    done
  done;
  rgba32
;;

