/*
 *  GRUB  --  GRand Unified Bootloader
 *  Copyright (C) 2006,2007  Free Software Foundation, Inc.
 *
 *  GRUB 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 3 of the License, or
 *  (at your option) any later version.
 *
 *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <grub/video.h>
#include <grub/bitmap.h>
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/mm.h>
#include <grub/misc.h>
#include <grub/i18n.h>

GRUB_MOD_LICENSE ("GPLv3+");

/* List of bitmap readers registered to system.  */
static grub_video_bitmap_reader_t bitmap_readers_list;

/* Register bitmap reader.  */
void
grub_video_bitmap_reader_register (grub_video_bitmap_reader_t reader)
{
  reader->next = bitmap_readers_list;
  bitmap_readers_list = reader;
}

/* Unregister bitmap reader.  */
void
grub_video_bitmap_reader_unregister (grub_video_bitmap_reader_t reader)
{
  grub_video_bitmap_reader_t *p, q;

  for (p = &bitmap_readers_list, q = *p; q; p = &(q->next), q = q->next)
    if (q == reader)
      {
        *p = q->next;
        break;
      }
}

/* Creates new bitmap, saves created bitmap on success to *bitmap.  */
grub_err_t
grub_video_bitmap_create (struct grub_video_bitmap **bitmap,
                          unsigned int width, unsigned int height,
                          enum grub_video_blit_format blit_format)
{
  struct grub_video_mode_info *mode_info;
  unsigned int size;

  if (!bitmap)
    return grub_error (GRUB_ERR_BUG, "invalid argument");

  *bitmap = 0;

  if (width == 0 || height == 0)
    return grub_error (GRUB_ERR_BUG, "invalid argument");

  *bitmap = (struct grub_video_bitmap *)grub_malloc (sizeof (struct grub_video_bitmap));
  if (! *bitmap)
    return grub_errno;

  mode_info = &((*bitmap)->mode_info);

  /* Populate mode_info.  */
  mode_info->width = width;
  mode_info->height = height;
  mode_info->blit_format = blit_format;

  switch (blit_format)
    {
      case GRUB_VIDEO_BLIT_FORMAT_RGBA_8888:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB
                               | GRUB_VIDEO_MODE_TYPE_ALPHA;
        mode_info->bpp = 32;
        mode_info->bytes_per_pixel = 4;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 8;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 8;
        mode_info->green_field_pos = 8;
        mode_info->blue_mask_size = 8;
        mode_info->blue_field_pos = 16;
        mode_info->reserved_mask_size = 8;
        mode_info->reserved_field_pos = 24;
        break;

      case GRUB_VIDEO_BLIT_FORMAT_RGB_888:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_RGB;
        mode_info->bpp = 24;
        mode_info->bytes_per_pixel = 3;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 8;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 8;
        mode_info->green_field_pos = 8;
        mode_info->blue_mask_size = 8;
        mode_info->blue_field_pos = 16;
        mode_info->reserved_mask_size = 0;
        mode_info->reserved_field_pos = 0;
        break;

      case GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR:
        mode_info->mode_type = GRUB_VIDEO_MODE_TYPE_INDEX_COLOR;
        mode_info->bpp = 8;
        mode_info->bytes_per_pixel = 1;
        mode_info->number_of_colors = 256;
        mode_info->red_mask_size = 0;
        mode_info->red_field_pos = 0;
        mode_info->green_mask_size = 0;
        mode_info->green_field_pos = 0;
        mode_info->blue_mask_size = 0;
        mode_info->blue_field_pos = 0;
        mode_info->reserved_mask_size = 0;
        mode_info->reserved_field_pos = 0;
        break;

      default:
        grub_free (*bitmap);
        *bitmap = 0;

        return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                           "unsupported bitmap format");
    }

  mode_info->pitch = width * mode_info->bytes_per_pixel;

  /* Calculate size needed for the data.  */
  size = (width * mode_info->bytes_per_pixel) * height;

  (*bitmap)->data = grub_zalloc (size);
  if (! (*bitmap)->data)
    {
      grub_free (*bitmap);
      *bitmap = 0;

      return grub_errno;
    }

  return GRUB_ERR_NONE;
}

/* Frees all resources allocated by bitmap.  */
grub_err_t
grub_video_bitmap_destroy (struct grub_video_bitmap *bitmap)
{
  if (! bitmap)
    return GRUB_ERR_NONE;

  grub_free (bitmap->data);
  grub_free (bitmap);

  return GRUB_ERR_NONE;
}

/* Match extension to filename.  */
static int
match_extension (const char *filename, const char *ext)
{
  int pos;
  int ext_len;

  pos = grub_strlen (filename);
  ext_len = grub_strlen (ext);

  if (! pos || ! ext_len || ext_len > pos)
    return 0;

  pos -= ext_len;

  return grub_strcasecmp (filename + pos, ext) == 0;
}

/* Loads bitmap using registered bitmap readers.  */
grub_err_t
grub_video_bitmap_load (struct grub_video_bitmap **bitmap,
                        const char *filename)
{
  grub_video_bitmap_reader_t reader = bitmap_readers_list;

  if (!bitmap)
    return grub_error (GRUB_ERR_BUG, "invalid argument");

  *bitmap = 0;

  while (reader)
    {
      if (match_extension (filename, reader->extension))
        return reader->reader (bitmap, filename);

      reader = reader->next;
    }

  return grub_error (GRUB_ERR_BAD_FILE_TYPE,
		     /* TRANSLATORS: We're speaking about bitmap images like
			JPEG or PNG.  */
		     N_("bitmap file `%s' is of"
			" unsupported format"), filename);
}

/* Return mode info for bitmap.  */
void grub_video_bitmap_get_mode_info (struct grub_video_bitmap *bitmap,
                                      struct grub_video_mode_info *mode_info)
{
  if (!bitmap)
    return;

  *mode_info = bitmap->mode_info;
}

/* Return pointer to bitmap's raw data.  */
void *grub_video_bitmap_get_data (struct grub_video_bitmap *bitmap)
{
  if (!bitmap)
    return 0;

  return bitmap->data;
}

