//! The unit of processing passing through a pipeline.

use std::fmt;

/// Color of a grid cell on a Product.
#[derive(Clone,Copy,Debug,Eq,PartialEq)]
pub enum Color {
    Unset,
    Red,
    Green,
    Blue,
}

impl Color {
    fn short(&self) -> &'static str {
        match *self {
            Color::Unset => " ",
            Color::Red => "R",
            Color::Green => "G",
            Color::Blue => "B",
        }
    }
}

impl Default for Color {
    fn default() -> Self {
        Color::Unset
    }
}

/// Size of the 2D color grid on a Product.
pub const GRID_SIZE: usize = 3;

/// Color grid type used in Products.
pub type ColorGrid = [[Color; GRID_SIZE]; GRID_SIZE];

/// Product is the unit of processing.
///
/// Products are fed into the processing network, mutated, and output.
#[derive(Clone,Debug,Default,Eq,PartialEq)]
pub struct Product {
    pub color_grid: ColorGrid,
}

impl Product {
    /// Creates a `Product` with the given ColorGrid.
    pub fn from_grid(grid: ColorGrid) -> Self {
        Product { color_grid: grid }
    }

    /// Creates a `Product` filled with the given `Color`.
    pub fn with_color(color: Color) -> Self 

}

impl fmt::Display for Product {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        for row in &self.color_grid {
            for cell in row {
                try!(f.write_str(cell.short()));
            }
            try!(f.write_str(","));
        }
        Ok(())
    }
}

{
        let mut colors = ColorGrid::default();
        for row in &mut colors {
            for mut cell in row {
                *cell = color;
            }
        }
        Product { color_grid: colors }
    }