use crate::gradient::EvalGradient;
use crate::{interpolate, Color, Gradient};

#[derive(Copy, Clone)]
struct Diverging {
    name: &'static str,
    three: [Color; 3],
    four: [Color; 4],
    five: [Color; 5],
    six: [Color; 6],
    seven: [Color; 7],
    eight: [Color; 8],
    nine: [Color; 9],
    ten: [Color; 10],
    eleven: [Color; 11],
}

impl EvalGradient for Diverging {
    fn name(&self) -> &'static str {
        self.name
    }

    fn eval_rational(&self, i: usize, n: usize) -> Color {
        match n {
            0 | 1 => self.three[2],
            2 => self.three[i * 2],
            3 => self.three[i],
            4 => self.four[i],
            5 => self.five[i],
            6 => self.six[i],
            7 => self.seven[i],
            8 => self.eight[i],
            9 => self.nine[i],
            10 => self.ten[i],
            11 => self.eleven[i],
            _ => self.eval_continuous(i as f32 / (n - 1) as f32),
        }
    }

    fn eval_continuous(&self, t: f32) -> Color {
        interpolate::spline(&self.eleven, t)
    }
}

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/BrBG.png" width="100%" height="40" alt="BrBG">
pub const BROWN_GREEN: Gradient = Gradient {
    eval: &Diverging {
        name: "BrBG",
        three: colors!(0xd8b365 0xf5f5f5 0x5ab4ac),
        four: colors!(0xa6611a 0xdfc27d 0x80cdc1 0x018571),
        five: colors!(0xa6611a 0xdfc27d 0xf5f5f5 0x80cdc1 0x018571),
        six: colors!(0x8c510a 0xd8b365 0xf6e8c3 0xc7eae5 0x5ab4ac 0x01665e),
        seven: colors!(0x8c510a 0xd8b365 0xf6e8c3 0xf5f5f5 0xc7eae5 0x5ab4ac 0x01665e),
        eight: colors!(0x8c510a 0xbf812d 0xdfc27d 0xf6e8c3 0xc7eae5 0x80cdc1 0x35978f 0x01665e),
        nine: colors!(0x8c510a 0xbf812d 0xdfc27d 0xf6e8c3 0xf5f5f5 0xc7eae5 0x80cdc1 0x35978f 0x01665e),
        ten: colors!(0x543005 0x8c510a 0xbf812d 0xdfc27d 0xf6e8c3 0xc7eae5 0x80cdc1 0x35978f 0x01665e 0x003c30),
        eleven: colors!(0x543005 0x8c510a 0xbf812d 0xdfc27d 0xf6e8c3 0xf5f5f5 0xc7eae5 0x80cdc1 0x35978f 0x01665e 0x003c30),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/PRGn.png" width="100%" height="40" alt="PRGn">
pub const PURPLE_GREEN: Gradient = Gradient {
    eval: &Diverging {
        name: "PRGn",
        three: colors!(0xaf8dc3 0xf7f7f7 0x7fbf7b),
        four: colors!(0x7b3294 0xc2a5cf 0xa6dba0 0x008837),
        five: colors!(0x7b3294 0xc2a5cf 0xf7f7f7 0xa6dba0 0x008837),
        six: colors!(0x762a83 0xaf8dc3 0xe7d4e8 0xd9f0d3 0x7fbf7b 0x1b7837),
        seven: colors!(0x762a83 0xaf8dc3 0xe7d4e8 0xf7f7f7 0xd9f0d3 0x7fbf7b 0x1b7837),
        eight: colors!(0x762a83 0x9970ab 0xc2a5cf 0xe7d4e8 0xd9f0d3 0xa6dba0 0x5aae61 0x1b7837),
        nine: colors!(0x762a83 0x9970ab 0xc2a5cf 0xe7d4e8 0xf7f7f7 0xd9f0d3 0xa6dba0 0x5aae61 0x1b7837),
        ten: colors!(0x40004b 0x762a83 0x9970ab 0xc2a5cf 0xe7d4e8 0xd9f0d3 0xa6dba0 0x5aae61 0x1b7837 0x00441b),
        eleven: colors!(0x40004b 0x762a83 0x9970ab 0xc2a5cf 0xe7d4e8 0xf7f7f7 0xd9f0d3 0xa6dba0 0x5aae61 0x1b7837 0x00441b),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/PiYG.png" width="100%" height="40" alt="PiYG">
pub const PINK_GREEN: Gradient = Gradient {
    eval: &Diverging {
        name: "PiYG",
        three: colors!(0xe9a3c9 0xf7f7f7 0xa1d76a),
        four: colors!(0xd01c8b 0xf1b6da 0xb8e186 0x4dac26),
        five: colors!(0xd01c8b 0xf1b6da 0xf7f7f7 0xb8e186 0x4dac26),
        six: colors!(0xc51b7d 0xe9a3c9 0xfde0ef 0xe6f5d0 0xa1d76a 0x4d9221),
        seven: colors!(0xc51b7d 0xe9a3c9 0xfde0ef 0xf7f7f7 0xe6f5d0 0xa1d76a 0x4d9221),
        eight: colors!(0xc51b7d 0xde77ae 0xf1b6da 0xfde0ef 0xe6f5d0 0xb8e186 0x7fbc41 0x4d9221),
        nine: colors!(0xc51b7d 0xde77ae 0xf1b6da 0xfde0ef 0xf7f7f7 0xe6f5d0 0xb8e186 0x7fbc41 0x4d9221),
        ten: colors!(0x8e0152 0xc51b7d 0xde77ae 0xf1b6da 0xfde0ef 0xe6f5d0 0xb8e186 0x7fbc41 0x4d9221 0x276419),
        eleven: colors!(0x8e0152 0xc51b7d 0xde77ae 0xf1b6da 0xfde0ef 0xf7f7f7 0xe6f5d0 0xb8e186 0x7fbc41 0x4d9221 0x276419),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/PuOr.png" width="100%" height="40" alt="PuOr">
pub const PURPLE_ORANGE: Gradient = Gradient {
    eval: &Diverging {
        name: "PuOr",
        three: colors!(0x998ec3 0xf7f7f7 0xf1a340),
        four: colors!(0x5e3c99 0xb2abd2 0xfdb863 0xe66101),
        five: colors!(0x5e3c99 0xb2abd2 0xf7f7f7 0xfdb863 0xe66101),
        six: colors!(0x542788 0x998ec3 0xd8daeb 0xfee0b6 0xf1a340 0xb35806),
        seven: colors!(0x542788 0x998ec3 0xd8daeb 0xf7f7f7 0xfee0b6 0xf1a340 0xb35806),
        eight: colors!(0x542788 0x8073ac 0xb2abd2 0xd8daeb 0xfee0b6 0xfdb863 0xe08214 0xb35806),
        nine: colors!(0x542788 0x8073ac 0xb2abd2 0xd8daeb 0xf7f7f7 0xfee0b6 0xfdb863 0xe08214 0xb35806),
        ten: colors!(0x2d004b 0x542788 0x8073ac 0xb2abd2 0xd8daeb 0xfee0b6 0xfdb863 0xe08214 0xb35806 0x7f3b08),
        eleven: colors!(0x2d004b 0x542788 0x8073ac 0xb2abd2 0xd8daeb 0xf7f7f7 0xfee0b6 0xfdb863 0xe08214 0xb35806 0x7f3b08),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/RdBu.png" width="100%" height="40" alt="RdBu">
pub const RED_BLUE: Gradient = Gradient {
    eval: &Diverging {
        name: "RdBu",
        three: colors!(0xef8a62 0xf7f7f7 0x67a9cf),
        four: colors!(0xca0020 0xf4a582 0x92c5de 0x0571b0),
        five: colors!(0xca0020 0xf4a582 0xf7f7f7 0x92c5de 0x0571b0),
        six: colors!(0xb2182b 0xef8a62 0xfddbc7 0xd1e5f0 0x67a9cf 0x2166ac),
        seven: colors!(0xb2182b 0xef8a62 0xfddbc7 0xf7f7f7 0xd1e5f0 0x67a9cf 0x2166ac),
        eight: colors!(0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xd1e5f0 0x92c5de 0x4393c3 0x2166ac),
        nine: colors!(0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xf7f7f7 0xd1e5f0 0x92c5de 0x4393c3 0x2166ac),
        ten: colors!(0x67001f 0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xd1e5f0 0x92c5de 0x4393c3 0x2166ac 0x053061),
        eleven: colors!(0x67001f 0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xf7f7f7 0xd1e5f0 0x92c5de 0x4393c3 0x2166ac 0x053061),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/RdGy.png" width="100%" height="40" alt="RdGy">
pub const RED_GREY: Gradient = Gradient {
    eval: &Diverging {
        name: "RdGy",
        three: colors!(0xef8a62 0xffffff 0x999999),
        four: colors!(0xca0020 0xf4a582 0xbababa 0x404040),
        five: colors!(0xca0020 0xf4a582 0xffffff 0xbababa 0x404040),
        six: colors!(0xb2182b 0xef8a62 0xfddbc7 0xe0e0e0 0x999999 0x4d4d4d),
        seven: colors!(0xb2182b 0xef8a62 0xfddbc7 0xffffff 0xe0e0e0 0x999999 0x4d4d4d),
        eight: colors!(0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xe0e0e0 0xbababa 0x878787 0x4d4d4d),
        nine: colors!(0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xffffff 0xe0e0e0 0xbababa 0x878787 0x4d4d4d),
        ten: colors!(0x67001f 0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xe0e0e0 0xbababa 0x878787 0x4d4d4d 0x1a1a1a),
        eleven: colors!(0x67001f 0xb2182b 0xd6604d 0xf4a582 0xfddbc7 0xffffff 0xe0e0e0 0xbababa 0x878787 0x4d4d4d 0x1a1a1a),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/RdYlBu.png" width="100%" height="40" alt="RdYlBu">
pub const RED_YELLOW_BLUE: Gradient = Gradient {
    eval: &Diverging {
        name: "RdYlBu",
        three: colors!(0xfc8d59 0xffffbf 0x91bfdb),
        four: colors!(0xd7191c 0xfdae61 0xabd9e9 0x2c7bb6),
        five: colors!(0xd7191c 0xfdae61 0xffffbf 0xabd9e9 0x2c7bb6),
        six: colors!(0xd73027 0xfc8d59 0xfee090 0xe0f3f8 0x91bfdb 0x4575b4),
        seven: colors!(0xd73027 0xfc8d59 0xfee090 0xffffbf 0xe0f3f8 0x91bfdb 0x4575b4),
        eight: colors!(0xd73027 0xf46d43 0xfdae61 0xfee090 0xe0f3f8 0xabd9e9 0x74add1 0x4575b4),
        nine: colors!(0xd73027 0xf46d43 0xfdae61 0xfee090 0xffffbf 0xe0f3f8 0xabd9e9 0x74add1 0x4575b4),
        ten: colors!(0xa50026 0xd73027 0xf46d43 0xfdae61 0xfee090 0xe0f3f8 0xabd9e9 0x74add1 0x4575b4 0x313695),
        eleven: colors!(0xa50026 0xd73027 0xf46d43 0xfdae61 0xfee090 0xffffbf 0xe0f3f8 0xabd9e9 0x74add1 0x4575b4 0x313695),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/RdYlGn.png" width="100%" height="40" alt="RdYlGn">
pub const RED_YELLOW_GREEN: Gradient = Gradient {
    eval: &Diverging {
        name: "RdYlGn",
        three: colors!(0xfc8d59 0xffffbf 0x91cf60),
        four: colors!(0xd7191c 0xfdae61 0xa6d96a 0x1a9641),
        five: colors!(0xd7191c 0xfdae61 0xffffbf 0xa6d96a 0x1a9641),
        six: colors!(0xd73027 0xfc8d59 0xfee08b 0xd9ef8b 0x91cf60 0x1a9850),
        seven: colors!(0xd73027 0xfc8d59 0xfee08b 0xffffbf 0xd9ef8b 0x91cf60 0x1a9850),
        eight: colors!(0xd73027 0xf46d43 0xfdae61 0xfee08b 0xd9ef8b 0xa6d96a 0x66bd63 0x1a9850),
        nine: colors!(0xd73027 0xf46d43 0xfdae61 0xfee08b 0xffffbf 0xd9ef8b 0xa6d96a 0x66bd63 0x1a9850),
        ten: colors!(0xa50026 0xd73027 0xf46d43 0xfdae61 0xfee08b 0xd9ef8b 0xa6d96a 0x66bd63 0x1a9850 0x006837),
        eleven: colors!(0xa50026 0xd73027 0xf46d43 0xfdae61 0xfee08b 0xffffbf 0xd9ef8b 0xa6d96a 0x66bd63 0x1a9850 0x006837),
    },
};

/// &#8203;
///
/// <img src="https://raw.githubusercontent.com/dtolnay/colorous/readme/Spectral.png" width="100%" height="40" alt="Spectral">
pub const SPECTRAL: Gradient = Gradient {
    eval: &Diverging {
        name: "Spectral",
        three: colors!(0xfc8d59 0xffffbf 0x99d594),
        four: colors!(0xd7191c 0xfdae61 0xabdda4 0x2b83ba),
        five: colors!(0xd7191c 0xfdae61 0xffffbf 0xabdda4 0x2b83ba),
        six: colors!(0xd53e4f 0xfc8d59 0xfee08b 0xe6f598 0x99d594 0x3288bd),
        seven: colors!(0xd53e4f 0xfc8d59 0xfee08b 0xffffbf 0xe6f598 0x99d594 0x3288bd),
        eight: colors!(0xd53e4f 0xf46d43 0xfdae61 0xfee08b 0xe6f598 0xabdda4 0x66c2a5 0x3288bd),
        nine: colors!(0xd53e4f 0xf46d43 0xfdae61 0xfee08b 0xffffbf 0xe6f598 0xabdda4 0x66c2a5 0x3288bd),
        ten: colors!(0x9e0142 0xd53e4f 0xf46d43 0xfdae61 0xfee08b 0xe6f598 0xabdda4 0x66c2a5 0x3288bd 0x5e4fa2),
        eleven: colors!(0x9e0142 0xd53e4f 0xf46d43 0xfdae61 0xfee08b 0xffffbf 0xe6f598 0xabdda4 0x66c2a5 0x3288bd 0x5e4fa2),
    },
};
