use super::Style;

/// When printing out one colored string followed by another, use one of
/// these rules to figure out which *extra* control codes need to be sent.
#[derive(PartialEq, Clone, Copy, Debug)]
pub enum Difference {
    /// Print out the control codes specified by this style to end up looking
    /// like the second string's styles.
    ExtraStyles(Style),

    /// Converting between these two is impossible, so just send a reset
    /// command and then the second string's styles.
    Reset,

    /// The before style is exactly the same as the after style, so no further
    /// control codes need to be printed.
    Empty,
}

impl Difference {
    /// Compute the 'style difference' required to turn an existing style into
    /// the given, second style.
    ///
    /// For example, to turn green text into green bold text, it's redundant
    /// to write a reset command then a second green+bold command, instead of
    /// just writing one bold command. This method should see that both styles
    /// use the foreground color green, and reduce it to a single command.
    ///
    /// This method returns an enum value because it's not actually always
    /// possible to turn one style into another: for example, text could be
    /// made bold and underlined, but you can't remove the bold property
    /// without also removing the underline property. So when this has to
    /// happen, this function returns None, meaning that the entire set of
    /// styles should be reset and begun again.
    pub fn between(first: &Style, next: &Style) -> Difference {
        use self::Difference::*;

        // XXX(Havvy): This algorithm is kind of hard to replicate without
        // having the Plain/Foreground enum variants, so I'm just leaving
        // it commented out for now, and defaulting to Reset.

        if first == next {
            return Empty;
        }

        // Cannot un-bold, so must Reset.
        if first.is_bold && !next.is_bold {
            return Reset;
        }

        if first.is_dimmed && !next.is_dimmed {
            return Reset;
        }

        if first.is_italic && !next.is_italic {
            return Reset;
        }

        // Cannot un-underline, so must Reset.
        if first.is_underline && !next.is_underline {
            return Reset;
        }

        if first.is_blink && !next.is_blink {
            return Reset;
        }

        if first.is_reverse && !next.is_reverse {
            return Reset;
        }

        if first.is_hidden && !next.is_hidden {
            return Reset;
        }

        if first.is_strikethrough && !next.is_strikethrough {
            return Reset;
        }

        // Cannot go from foreground to no foreground, so must Reset.
        if first.foreground.is_some() && next.foreground.is_none() {
            return Reset;
        }

        // Cannot go from background to no background, so must Reset.
        if first.background.is_some() && next.background.is_none() {
            return Reset;
        }

        let mut extra_styles = Style::default();

        if first.is_bold != next.is_bold {
            extra_styles.is_bold = true;
        }

        if first.is_dimmed != next.is_dimmed {
            extra_styles.is_dimmed = true;
        }

        if first.is_italic != next.is_italic {
            extra_styles.is_italic = true;
        }

        if first.is_underline != next.is_underline {
            extra_styles.is_underline = true;
        }

        if first.is_blink != next.is_blink {
            extra_styles.is_blink = true;
        }

        if first.is_reverse != next.is_reverse {
            extra_styles.is_reverse = true;
        }

        if first.is_hidden != next.is_hidden {
            extra_styles.is_hidden = true;
        }

        if first.is_strikethrough != next.is_strikethrough {
            extra_styles.is_strikethrough = true;
        }

        if first.foreground != next.foreground {
            extra_styles.foreground = next.foreground;
        }

        if first.background != next.background {
            extra_styles.background = next.background;
        }

        ExtraStyles(extra_styles)
    }
}

#[cfg(test)]
mod test {
    use super::Difference::*;
    use super::*;
    use crate::style::Color::*;
    use crate::style::Style;

    fn style() -> Style {
        Style::new()
    }

    macro_rules! test {
        ($name: ident: $first: expr; $next: expr => $result: expr) => {
            #[test]
            fn $name() {
                assert_eq!($result, Difference::between(&$first, &$next));
            }
        };
    }

    test!(nothing:    Green.normal(); Green.normal()  => Empty);
    test!(uppercase:  Green.normal(); Green.bold()    => ExtraStyles(style().bold()));
    test!(lowercase:  Green.bold();   Green.normal()  => Reset);
    test!(nothing2:   Green.bold();   Green.bold()    => Empty);

    test!(color_change: Red.normal(); Blue.normal() => ExtraStyles(Blue.normal()));

    test!(addition_of_blink:          style(); style().blink()          => ExtraStyles(style().blink()));
    test!(addition_of_dimmed:         style(); style().dimmed()         => ExtraStyles(style().dimmed()));
    test!(addition_of_hidden:         style(); style().hidden()         => ExtraStyles(style().hidden()));
    test!(addition_of_reverse:        style(); style().reverse()        => ExtraStyles(style().reverse()));
    test!(addition_of_strikethrough:  style(); style().strikethrough()  => ExtraStyles(style().strikethrough()));

    test!(removal_of_strikethrough:   style().strikethrough(); style()  => Reset);
    test!(removal_of_reverse:         style().reverse();       style()  => Reset);
    test!(removal_of_hidden:          style().hidden();        style()  => Reset);
    test!(removal_of_dimmed:          style().dimmed();        style()  => Reset);
    test!(removal_of_blink:           style().blink();         style()  => Reset);
}
