use super::Style;


/// When printing out one coloured 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.
    NoDifference,
}


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 colour 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 NoDifference;
        }

        // 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::*;
    use super::Difference::*;
    use style::Colour::*;
    use 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()  => NoDifference);
    test!(uppercase:  Green.normal(); Green.bold()    => ExtraStyles(style().bold()));
    test!(lowercase:  Green.bold();   Green.normal()  => Reset);
    test!(nothing2:   Green.bold();   Green.bold()    => NoDifference);

    test!(colour_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);
}
