use super::DoubleValue;
use super::StringValue;
use super::Theme;
use super::UInt32Value;
use quick_xml::events::BytesStart;
use quick_xml::Reader;
use quick_xml::Writer;
use reader::driver::*;
use std::io::Cursor;
use writer::driver::*;
const INDEXED_COLORS: &'static [&'static str] = &[
"FF000000", "FFFFFFFF", "FFFF0000", "FF00FF00", "FF0000FF", "FFFFFF00", "FFFF00FF", "FF00FFFF", "FF800000", "FF008000", "FF000080", "FF808000", "FF800080", "FF008080", "FFC0C0C0", "FF808080", "FF9999FF", "FF993366", "FFFFFFCC", "FFCCFFFF", "FF660066", "FFFF8080", "FF0066CC", "FFCCCCFF", "FF000080", "FFFF00FF", "FFFFFF00", "FF00FFFF", "FF800080", "FF800000", "FF008080", "FF0000FF", "FF00CCFF", "FFCCFFFF", "FFCCFFCC", "FFFFFF99", "FF99CCFF", "FFFF99CC", "FFCC99FF", "FFFFCC99", "FF3366FF", "FF33CCCC", "FF99CC00", "FFFFCC00", "FFFF9900", "FFFF6600", "FF666699", "FF969696", "FF003366", "FF339966", "FF003300", "FF333300", "FF993300", "FF993366", "FF333399", "FF333333", ];
#[derive(Default, Debug, Clone)]
pub struct TabColor {
indexed: UInt32Value,
theme_index: UInt32Value,
argb: StringValue,
tint: DoubleValue,
}
impl TabColor {
pub const NAMED_COLORS: &'static [&'static str] = &[
"Black", "White", "Red", "Green", "Blue", "Yellow", "Magenta", "Cyan",
];
pub const COLOR_BLACK: &'static str = "FF000000";
pub const COLOR_WHITE: &'static str = "FFFFFFFF";
pub const COLOR_RED: &'static str = "FFFF0000";
pub const COLOR_DARKRED: &'static str = "FF800000";
pub const COLOR_BLUE: &'static str = "FF0000FF";
pub const COLOR_DARKBLUE: &'static str = "FF000080";
pub const COLOR_GREEN: &'static str = "FF00FF00";
pub const COLOR_DARKGREEN: &'static str = "FF008000";
pub const COLOR_YELLOW: &'static str = "FFFFFF00";
pub const COLOR_DARKYELLOW: &'static str = "FF808000";
#[inline]
pub fn get_argb(&self) -> &str {
&self.argb.get_value()
}
#[inline]
pub fn set_argb<S: Into<String>>(&mut self, value: S) -> &mut Self {
self.indexed.remove_value();
self.theme_index.remove_value();
self.argb.set_value(value);
self
}
#[inline]
pub fn get_indexed(&self) -> &u32 {
&self.indexed.get_value()
}
pub fn set_indexed(&mut self, index: u32) -> &mut Self {
self.indexed.set_value(index);
self.theme_index.remove_value();
self.argb
.set_value(match INDEXED_COLORS.get(index as usize - 1) {
Some(v) => v.to_string(),
None => String::new(),
});
self
}
#[inline]
pub fn get_theme_index(&self) -> &u32 {
&self.theme_index.get_value()
}
#[inline]
pub fn set_theme_index(&mut self, index: u32) -> &mut Self {
self.indexed.remove_value();
self.theme_index.set_value(index);
self.argb.remove_value();
self
}
pub(crate) fn set_argb_by_theme(&mut self, theme: &Theme) -> &mut Self {
if self.theme_index.has_value() {
self.argb.set_value(
match theme
.get_color_map()
.get(self.theme_index.get_value().clone() as usize)
{
Some(v) => v.to_string(),
None => String::new(),
},
);
}
self
}
#[inline]
pub fn get_tint(&self) -> &f64 {
&self.tint.get_value()
}
#[inline]
pub fn set_tint(&mut self, value: f64) -> &mut Self {
self.tint.set_value(value);
self
}
#[inline]
pub(crate) fn has_value(&self) -> bool {
self.theme_index.has_value()
|| self.indexed.has_value()
|| self.argb.has_value()
|| self.tint.has_value()
}
#[inline]
pub(crate) fn get_hash_code(&self) -> String {
format!(
"{:x}",
md5::Md5::digest(format!(
"{}{}{}{}",
&self.indexed.get_hash_string(),
&self.theme_index.get_hash_string(),
&self.argb.get_hash_string(),
&self.tint.get_hash_string()
))
)
}
pub(crate) fn set_attributes<R: std::io::BufRead>(
&mut self,
_reader: &mut Reader<R>,
e: &BytesStart,
) {
for a in e.attributes().with_checks(false) {
match a {
Ok(ref attr) if attr.key.0 == b"indexed" => {
self.indexed
.set_value_string(get_attribute_value(attr).unwrap());
}
Ok(ref attr) if attr.key.0 == b"theme" => {
self.theme_index
.set_value_string(get_attribute_value(attr).unwrap());
}
Ok(ref attr) if attr.key.0 == b"rgb" => {
self.argb
.set_value_string(get_attribute_value(attr).unwrap());
}
Ok(ref attr) if attr.key.0 == b"tint" => {
self.tint
.set_value_string(get_attribute_value(attr).unwrap());
}
Ok(_) => {}
Err(_) => {}
}
}
}
pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
let mut attributes: Vec<(&str, &str)> = Vec::new();
if self.theme_index.has_value() {
attributes.push(("theme", self.theme_index.get_value_string()));
} else if self.indexed.has_value() {
attributes.push(("indexed", self.indexed.get_value_string()));
} else if self.argb.has_value() {
attributes.push(("rgb", self.argb.get_value_string()));
}
if self.tint.has_value() {
attributes.push(("tint", self.tint.get_value_string()));
}
if attributes.len() > 0 {
write_start_tag(writer, "tabColor", attributes, true);
}
}
}