/*  OpenTally: Open-source election vote counting
 *  Copyright © 2021 Lee Yingtong Li (RunasSudo)
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

use itertools::Itertools;

/// Table
pub struct Table {
	/// Rows in the table
	rows: Vec<Row>,
}

impl Table {
	/// Return a new [Table]
	pub fn new() -> Self {
		Self {
			rows: Vec::new(),
		}
	}
	
	/// Add a [Row] to the table
	pub fn add_row(&mut self, row: Row) {
		self.rows.push(row);
	}
	
	/// Alias for [add_row]
	pub fn set_titles(&mut self, row: Row) {
		self.add_row(row);
	}
	
	/// Render the table as HTML
	pub fn to_html(&self) -> String {
		return format!(r#"<table class="transfers">{}</table>"#, self.rows.iter().map(|r| r.to_html()).join(""));
	}
}

/// Row in a [Table]
pub struct Row {
	/// Cells in the row
	cells: Vec<Cell>,
}

impl Row {
	/// Return a new [Row]
	pub fn new(cells: Vec<Cell>) -> Self {
		Self {
			cells
		}
	}
	
	/// Render the row as HTML
	fn to_html(&self) -> String {
		return format!(r#"<tr>{}</tr>"#, self.cells.iter().map(|c| c.to_html()).join(""));
	}
}

/// Cell in a [Row]
pub struct Cell {
	/// Content of the cell
	content: String,
	/// HTML tag/attributes
	attrs: Vec<&'static str>,
}

impl Cell {
	/// Return a new [Cell]
	pub fn new(content: &str) -> Self {
		Self {
			content: String::from(content),
			attrs: vec!["td"],
		}
	}
	
	/// Apply a style to the cell
	#[allow(unused_mut)]
	pub fn style_spec(mut self, spec: &str) -> Self {
		if spec.contains("H2") {
			self.attrs.push(r#"colspan="2""#);
		}
		if spec.contains('c') {
			self.attrs.push(r#"style="text-align:center""#);
		}
		if spec.contains('r') {
			self.attrs.push(r#"style="text-align:right""#);
		}
		
		return self;
	}
	
	/// Render the cell as HTML
	fn to_html(&self) -> String {
		return format!(r#"<{}>{}</td>"#, self.attrs.join(" "), html_escape::encode_text(&self.content));
	}
}
