use half::f16;
use shared::Float;
use shared::core::color::{ColorEncoding, ColorEncodingTrait};

// Allows writing generic algorithms that work on any image format.
pub trait PixelStorageTrait: Copy + Send + Sync + 'static + PartialEq {
    fn from_linear(val: Float, encoding: ColorEncoding) -> Self;
    fn to_linear(self, encoding: ColorEncoding) -> Float;
}

impl PixelStorageTrait for f32 {
    #[inline(always)]
    fn from_linear(val: Float, _enc: ColorEncoding) -> Self {
        val
    }
    #[inline(always)]
    fn to_linear(self, _enc: ColorEncoding) -> Float {
        self
    }
}

impl PixelStorageTrait for f16 {
    #[inline(always)]
    fn from_linear(val: Float, _enc: ColorEncoding) -> Self {
        f16::from_f32(val)
    }
    #[inline(always)]
    fn to_linear(self, _enc: ColorEncoding) -> Float {
        self.to_f32()
    }
}

impl PixelStorageTrait for u8 {
    #[inline(always)]
    fn from_linear(val: Float, enc: ColorEncoding) -> Self {
        let mut out = [0u8];
        enc.from_linear(&[val], &mut out);
        out[0]
    }

    #[inline(always)]
    fn to_linear(self, enc: ColorEncoding) -> Float {
        let mut out = [0.0];
        enc.to_linear(&[self], &mut out);
        out[0]
    }
}
