// Aseprite Document Library
// Copyright (C) 2018-2024 Igara Studio S.A.
// Copyright (c) 2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.

#ifndef DOC_IMAGE_SPEC_H_INCLUDED
#define DOC_IMAGE_SPEC_H_INCLUDED
#pragma once

#include "base/debug.h"
#include "doc/color.h"
#include "doc/color_mode.h"
#include "gfx/color_space.h"
#include "gfx/rect.h"
#include "gfx/size.h"

namespace doc {

class ImageSpec {
public:
  ImageSpec(const ColorMode colorMode,
            const int width,
            const int height,
            const color_t maskColor = 0,
            const gfx::ColorSpaceRef& colorSpace = gfx::ColorSpace::MakeNone())
    : m_colorMode(colorMode)
    , m_size(width, height)
    , m_maskColor(maskColor)
    , m_colorSpace(colorSpace)
  {
    ASSERT(width > 0);
    ASSERT(height > 0);
  }

  ColorMode colorMode() const { return m_colorMode; }
  int width() const { return m_size.w; }
  int height() const { return m_size.h; }
  const gfx::Size& size() const { return m_size; }
  gfx::Rect bounds() const { return gfx::Rect(m_size); }
  const gfx::ColorSpaceRef& colorSpace() const { return m_colorSpace; }

  int bytesPerPixel() const { return bytes_per_pixel_for_colormode(m_colorMode); }

  int widthBytes() const { return bytesPerPixel() * width(); }

  // The transparent color for colored images (0 by default) or just 0 for RGBA and Grayscale
  color_t maskColor() const { return m_maskColor; }

  void setColorMode(const ColorMode colorMode) { m_colorMode = colorMode; }
  void setWidth(const int width) { m_size.w = width; }
  void setHeight(const int height) { m_size.h = height; }

  void setMaskColor(const color_t color)
  {
#if 0 // Sometimes, mask color = -1 is temporarily used to paint an
      // opaque indexed image in PixelsMovement.
      ASSERT(color != -1);
#endif
    m_maskColor = color;
  }

  void setColorSpace(const gfx::ColorSpaceRef& cs) { m_colorSpace = cs; }

  void setSize(const int width, const int height) { m_size = gfx::Size(width, height); }

  void setSize(const gfx::Size& sz) { m_size = sz; }

  bool operator==(const ImageSpec& that) const
  {
    return (m_colorMode == that.m_colorMode && m_size == that.m_size &&
            m_maskColor == that.m_maskColor &&
            ((!m_colorSpace && !that.m_colorSpace) ||
             (m_colorSpace && that.m_colorSpace && m_colorSpace->nearlyEqual(*that.m_colorSpace))));
  }
  bool operator!=(const ImageSpec& that) const { return !operator==(that); }

private:
  ColorMode m_colorMode;
  gfx::Size m_size;
  color_t m_maskColor;
  gfx::ColorSpaceRef m_colorSpace;
};

} // namespace doc

#endif
