use std::vec::Vec;
use std::collections::HashSet;
use async_channel::Sender;
use async_channel::SendError;
use iced::Element;
use iced::Row;
use iced::Column;
use iced::Text;
use iced::Checkbox;
use iced::scrollable;
use iced::Align;
use iced::button;
use iced::Length;
use install_framework_base::interface::InstallationState;
use install_framework_core::interface::Component;
use super::window::Page;
use super::window::ConstructiblePage;
use super::window::PageMessage;
use crate::messages::RenderMessage;
use crate::messages::ThreadMessage;
use crate::messages;
use crate::ext::SenderSync;
pub struct HomePage
{
available_components: Vec<Component>,
selected_components: HashSet<usize>,
install_state: Option<InstallationState>,
useless: scrollable::State,
useless1: button::State,
useless2: scrollable::State,
useless3: button::State,
uninstall: bool
}
impl ConstructiblePage for HomePage
{
type PageType = HomePage;
fn new(msg: &messages::Page) -> HomePage
{
if let messages::Page::ComponentView(comps, state, uninstall) = msg
{
return HomePage
{
available_components: comps.clone(),
selected_components: HashSet::new(),
install_state: state.clone(),
useless: scrollable::State::new(),
useless1: button::State::new(),
useless2: scrollable::State::new(),
useless3: button::State::new(),
uninstall: *uninstall
};
}
panic!("The impossible happened: incorrect message received");
}
}
impl Page for HomePage
{
fn handle_message(&mut self, _: &RenderMessage, _: &mut Sender<ThreadMessage>) -> Result<(), SendError<ThreadMessage>>
{
return Ok(());
}
fn update(&mut self, msg: &PageMessage, sender: &mut Sender<ThreadMessage>) -> Result<bool, SendError<ThreadMessage>>
{
match msg
{
PageMessage::ToggleComponent(id) =>
{
if self.selected_components.contains(id)
{
self.selected_components.remove(id);
}
else
{
self.selected_components.insert(*id);
}
},
PageMessage::Next =>
{
let mut comps = Vec::new();
for i in &self.selected_components
{
comps.push(self.available_components[*i].clone());
}
sender.send_sync(ThreadMessage::InstallComponents(comps))?;
},
PageMessage::Close => return Ok(true),
_ => ()
}
return Ok(false);
}
fn view(&mut self) -> Element<PageMessage>
{
let mut col = Column::new().spacing(5);
if let Some(state) = &self.install_state
{
col = col.push(Text::new("Installed components:"));
let mut scroll = scrollable::Scrollable::new(&mut self.useless2).spacing(5).width(Length::Fill).max_height(140);
for v in &state.installed_components
{
let mut r = Row::new().push(Text::new(&v.name));
if let Some(v1) = &v.version
{
r = r.push(Text::new(" ")).push(Text::new(v1));
}
scroll = scroll.push(r);
}
col = col.push(scroll).push(Text::new(" "));
}
col = col.push(Text::new("Available components:"));
for (i, v) in self.available_components.iter().enumerate()
{
col = col.push(
Checkbox::new(self.selected_components.contains(&i), &v.name, move |_| PageMessage::ToggleComponent(i))
);
}
col = col.push(Text::new(" "));
col = col.push(Text::new("Overview:"));
let mut scroll = scrollable::Scrollable::new(&mut self.useless).spacing(5).width(Length::Fill).max_height(140);
for i in &self.selected_components
{
let c = &self.available_components[*i];
if self.uninstall
{
scroll = scroll.push(Text::new(format!("Uninstall {}:", c.name)));
}
else
{
scroll = scroll.push(Text::new(format!("Install {}:", c.name)));
}
if let Some(v) = &c.version
{
scroll = scroll.push(
Row::new()
.align_items(Align::Center)
.push(Text::new("Version: "))
.push(Text::new(v)
)
);
}
if let Some(v) = &c.readme
{
scroll = scroll.push(Text::new("Readme:"));
scroll = scroll.push(Text::new(v));
}
if let Some(v) = &c.license
{
scroll = scroll.push(Text::new("License:"));
scroll = scroll.push(Text::new(v));
}
scroll = scroll.push(Text::new(" "));
}
col = col.push(scroll);
col = col.push(Text::new(" ")).push(Text::new(" "));
col = col.push(
Row::new()
.width(Length::Fill)
.push(
Column::new()
.width(Length::Fill)
.align_items(Align::Start)
.push(button::Button::new(&mut self.useless3, Text::new("Cancel & Close")).on_press(PageMessage::Close))
)
.push(
Column::new()
.width(Length::Fill)
.align_items(Align::End)
.push(button::Button::new(&mut self.useless1, Text::new("Next")).on_press(PageMessage::Next))
)
);
return col.into();
}
}