// Copyright 2026 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

///|
pub(all) struct ImageData {
  width : Int
  height : Int
  data : Bytes
} derive(Eq)

///|
pub(all) enum RasterColorCondition {
  SrgbCompatible
  EmbeddedColorProfile(String)
  HdrOrHighBitDepth(String)
} derive(Debug, Eq)

///|
pub(all) struct RasterColorMetadata {
  width : Int
  height : Int
  condition : RasterColorCondition
} derive(Debug, Eq)

///|
priv enum ColorType {
  Grayscale
  Rgb
  Indexed
  GrayscaleAlpha
  Rgba
}

///|
impl Show for ColorType with fn output(self, logger) {
  logger.write_string(
    match self {
      Grayscale => "Grayscale"
      Rgb => "Rgb"
      Indexed => "Indexed"
      GrayscaleAlpha => "GrayscaleAlpha"
      Rgba => "Rgba"
    },
  )
}

///|
priv struct IhdrData {
  width : Int
  height : Int
  bit_depth : Int
  color_type : ColorType
}

///|
pub(all) suberror DecodeError {
  InvalidSignature(String)
  InvalidChunkCrc(String)
  MissingChunk(String)
  UnsupportedFeature(String)
  CorruptData(String)
  DecodeLimitExceeded(String)
}

///|
pub impl Show for DecodeError with fn output(self, logger) {
  match self {
    InvalidSignature(s) => logger.write_string("InvalidSignature: " + s)
    InvalidChunkCrc(s) => logger.write_string("InvalidChunkCrc: " + s)
    MissingChunk(s) => logger.write_string("MissingChunk: " + s)
    UnsupportedFeature(s) => logger.write_string("UnsupportedFeature: " + s)
    CorruptData(s) => logger.write_string("CorruptData: " + s)
    DecodeLimitExceeded(s) => logger.write_string("DecodeLimitExceeded: " + s)
  }
}

///|
fn color_type_from_png(value : Int) -> ColorType raise DecodeError {
  match value {
    0 => Grayscale
    2 => Rgb
    3 => Indexed
    4 => GrayscaleAlpha
    6 => Rgba
    _ => raise UnsupportedFeature("unknown color type: " + value.to_string())
  }
}

///|
fn bytes_per_pixel(ct : ColorType, bit_depth : Int) -> Int {
  let channels = match ct {
    Grayscale => 1
    Rgb => 3
    Indexed => 1
    GrayscaleAlpha => 2
    Rgba => 4
  }
  let bits = channels * bit_depth
  if bits < 8 {
    1
  } else {
    bits / 8
  }
}