//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

use crate::s5;
// use crate::{behaviors::*, card::*};
use std::{thread, time};

pub struct Board {
    size: s5::Rect,
    card1: i32,
    card2: i32,
    matches: i32,
    elapsed: f64,
}

impl Board {
    pub const CARD_SIDE: f64 = 200.0;
    pub const ROWS: usize = 4;
    pub const COLUMNS: usize = 4;

    pub fn new(size: s5::Rect) -> Self {
        let mut behaviors_and_colors = Vec::new();
        for _ in 0..4 {
            behaviors_and_colors.push((true, s5::Color::RED));
            behaviors_and_colors.push((true, s5::Color::BLUE));
            behaviors_and_colors.push((false, s5::Color::YELLOW));
            behaviors_and_colors.push((false, s5::Color::GREEN));
        }
        let mut rng = s5::Rng::new();
        rng.shuffle(&mut behaviors_and_colors);

        // ... prepare something to store the cards to be built ...

        for row in 0..Board::ROWS {
            for column in 0..Board::COLUMNS {
                let (is_heart, color) = behaviors_and_colors.pop().unwrap();
                let _unused = (is_heart, color); // FIXME: remove when used

                // ... create the behavior (only at step 5)
                //     when is_heart is true
                //         then, the behavior is a « Heart » with color
                //     otherwise,
                //         the behavior is a « Diamond » with color ...

                // ... store a new Card with row, column
                //     and the behavior when you reach step 5 ...

                let _unused = (row, column); // FIXME: remove when used
            }
        }

        Self {
            size,
            card1: -1,
            card2: -1,
            matches: 8,
            elapsed: 0.0,
        }
    }

    pub fn size(&self) -> &s5::Rect {
        &self.size
    }

    pub fn resize(
        &mut self,
        size: s5::Rect,
    ) {
        self.size = size;
    }

    pub fn redraw(
        &self,
        screen: &mut s5::Screen,
    ) {
        screen.clear(s5::Color {
            r: 100,
            g: 100,
            b: 100,
        });

        // ... draw cards here ...
    }

    pub fn animate(
        &mut self,
        dt: f64,
    ) -> bool {
        self.elapsed += dt;

        if self.elapsed > 20.0 && self.matches > 0 {
            println!("TIME IS UP AND YOU LOST!");
            return false;
        }

        if self.matches == 0 {
            println!("AMAZING!! YOU WON!");
            return false;
        }

        if self.card1 != -1 && self.card2 != -1 {
            let i1 = self.card1 as usize;
            let i2 = self.card2 as usize;
            let _unused = (i1, i2); // FIXME: remove when used

            // ... if the card at index "i1" is like the card at index "i2" ...
            {
                // ... hide the card at index "i1" ...
                // ... hide the card at index "i2" ...
                self.matches -= 1;
            }
            // ... else ...
            {
                // ... flip the card at index "i1" ...
                // ... flip the card at index "i2" ...
            }

            thread::sleep(time::Duration::from_millis(200));
            self.card2 = -1;
            self.card1 = -1;
        }
        true // go on
    }

    pub fn click(
        &mut self,
        point: s5::Point,
    ) {
        let row = (point.y / Board::CARD_SIDE) as usize;
        let column = (point.x / Board::CARD_SIDE) as usize;
        let index = (row * Board::COLUMNS) + column;
        println!("click at ({},{}) in index {}", row, column, index);

        // ... determine if the card at index "index" is hidden ...
        let card_hidden = false /* ... to be changed ... */ ;

        // ... determine if the card at index "index" is flipped ...
        let card_flipped = false /* ... to be changed ... */ ;

        let mut must_flip = false;
        if !card_hidden {
            match card_flipped {
                true => {
                    if self.card1 == index as i32 {
                        self.card1 = -1;
                        must_flip = true;
                    } else if self.card2 == index as i32 {
                        self.card2 = -1;
                        must_flip = true;
                    }
                }
                false => {
                    if self.card1 == -1 {
                        self.card1 = index as i32;
                        must_flip = true;
                    } else if self.card2 == -1 {
                        self.card2 = index as i32;
                        must_flip = true;
                    }
                }
            }
        }

        if must_flip {
            // ... flip card at index "index" ...
        }
    }
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
