// Copyright 2022 The piet-gpu authors.
//
// 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
//
//     https://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.
//
// Also licensed under MIT license, at your choice.

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default, Debug)]
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl Color {
    pub const fn rgb8(r: u8, g: u8, b: u8) -> Self {
        Self { r, g, b, a: 255 }
    }

    pub const fn rgba8(r: u8, g: u8, b: u8, a: u8) -> Self {
        Self { r, g, b, a }
    }

    pub fn rgb<C: Into<f64>>(r: C, g: C, b: C) -> Self {
        Self::rgb8(
            (r.into() / 255.0) as u8,
            (g.into() / 255.0) as u8,
            (b.into() / 255.0) as u8,
        )
    }

    pub fn rgba<C: Into<f64>>(r: C, g: C, b: C, a: C) -> Self {
        Self::rgba8(
            (r.into() / 255.0) as u8,
            (g.into() / 255.0) as u8,
            (b.into() / 255.0) as u8,
            (a.into() / 255.0) as u8,
        )
    }

    pub fn pack(self) -> u32 {
        (self.b as u32) << 24 | (self.g as u32) << 16 | (self.r as u32) << 8 | self.a as u32
    }

    pub fn to_premul_u32(self) -> u32 {
        let a = self.a as f64 / 255.0;
        let r = (self.r as f64 * a) as u32;
        let g = (self.g as f64 * a) as u32;
        let b = (self.b as f64 * a) as u32;
        r | (g << 8) | (b << 16) | ((self.a as u32) << 24)
    }
}