/*
    This file is part of Post Maker.
    Post Maker is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    Post Maker 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 General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with Post Maker.  If not, see <https://www.gnu.org/licenses/>
*/

//! Main window where you do all editing
use crate::about::About;
use crate::crop_window::CropWindow;
use crate::draw_thread::*;
use crate::utils;
use crate::utils::ImageProperties;
use crate::{config_window::ConfigWindow, globals};
use fltk::{
    app,
    button::Button,
    dialog,
    dialog::NativeFileChooser,
    draw as dr, enums,
    enums::Shortcut,
    frame::Frame,
    group::Flex,
    image::SvgImage,
    input::{Input, MultilineInput},
    menu,
    misc::Spinner,
    prelude::*,
    valuator::{Slider, SliderType},
    window::Window,
};
use std::path::PathBuf;
use std::sync::{mpsc, RwLock};
use std::{ffi::OsStr, fs, sync::Arc};

pub(crate) struct MainWindow {
    pub(crate) win: Window,
    pub(crate) menubar: menu::SysMenuBar,
    pub(crate) back_btn: Button,
    pub(crate) next_btn: Button,
    pub(crate) save_btn: Button,
    /// To choose the file which is being edited in directory
    pub(crate) file_choice: menu::Choice,
    pub(crate) quote: MultilineInput,
    pub(crate) subquote: MultilineInput,
    pub(crate) subquote2: MultilineInput,
    pub(crate) tag: Input,
    pub(crate) tag2: Input,
    /// RGB value of top translucent layer
    pub(crate) translucent_layer_rgb: Button,
    /// opacity value of top translucent layer
    pub(crate) translucent_layer_alpha: Spinner,
    pub(crate) quote_position: Spinner,
    pub(crate) subquote_position: Spinner,
    pub(crate) subquote2_position: Spinner,
    pub(crate) tag_position: Spinner,
    pub(crate) tag2_position: Spinner,
    pub(crate) quote_position_slider: Slider,
    pub(crate) subquote_position_slider: Slider,
    pub(crate) subquote2_position_slider: Slider,
    pub(crate) tag_position_slider: Slider,
    pub(crate) tag2_position_slider: Slider,
    pub(crate) reset_translucent_layer_btn: Button,
    pub(crate) reset_quote_position_btn: Button,
    pub(crate) reset_subquote_position_btn: Button,
    pub(crate) reset_subquote2_position_btn: Button,
    pub(crate) reset_tag_position_btn: Button,
    pub(crate) reset_tag2_position_btn: Button,
    pub(crate) reset_file_choice: Button,
    pub(crate) crop_btn: Button,
    pub(crate) clone_btn: Button,
    pub(crate) delete_btn: Button,
    pub(crate) status: Frame,
    pub(crate) count: Frame,
    pub(crate) dimension: Frame,
    pub(crate) page: Page,
    pub(crate) images_path: Arc<RwLock<Vec<PathBuf>>>,
    pub(crate) draw_buff: Arc<RwLock<Option<Vec<u8>>>>,
    pub(crate) properties: Arc<RwLock<ImageProperties>>,
    pub(crate) sender: mpsc::Sender<DrawMessage>,
}

/// Contains the elements to draw page in mid of workspace
#[derive(Clone)]
pub(crate) struct Page {
    pub(crate) image: Frame,
    pub(crate) row_flex: Flex,
    pub(crate) col_flex: Flex,
}

impl MainWindow {
    pub(crate) fn new(
        sender: app::Sender<crate::AppMessage>,
        draw_buff: Arc<RwLock<Option<Vec<u8>>>>,
    ) -> Self {
        let mut win = Window::new(0, 0, 1100, 700, "Post Maker").center_screen();
        win.set_icon(Some(
            SvgImage::from_data(globals::ICON.to_str().unwrap()).unwrap(),
        ));

        let reload_image = SvgImage::from_data(globals::RELOAD_ICON.to_str().unwrap()).unwrap();

        let mut main_flex = Flex::default().size_of_parent().column();
        let menubar = menu::SysMenuBar::default();
        main_flex.set_size(&menubar, 30);

        let mut toolbar_flex = Flex::default().row();
        let back_btn = Button::default().with_label("Back");
        toolbar_flex.set_size(&back_btn, 50);
        let next_btn = Button::default().with_label("Next");
        toolbar_flex.set_size(&next_btn, 50);
        let save_btn = Button::default().with_label("Save");
        toolbar_flex.set_size(&save_btn, 50);
        let file_choice = menu::Choice::default();
        let mut reset_file_choice = Button::default();
        reset_file_choice.set_image(Some(reload_image.clone()));
        toolbar_flex.set_size(&reset_file_choice, 30);
        toolbar_flex.end();
        main_flex.set_size(&toolbar_flex, 30);

        let mut workspace_flex = Flex::default().row();
        // Controls Left
        let mut left_controls_flex = Flex::default().column();
        left_controls_flex.set_size(
            &Frame::default()
                .with_label("Quote:")
                .with_align(enums::Align::Left | enums::Align::Inside),
            25,
        );
        let quote = MultilineInput::default();
        left_controls_flex.set_size(&quote, 70);

        left_controls_flex.set_size(
            &Frame::default()
                .with_label("Subquote:")
                .with_align(enums::Align::Left | enums::Align::Inside),
            25,
        );
        let subquote = MultilineInput::default();
        left_controls_flex.set_size(&subquote, 70);

        left_controls_flex.set_size(
            &Frame::default()
                .with_label("Subquote 2:")
                .with_align(enums::Align::Left | enums::Align::Inside),
            25,
        );
        let subquote2 = MultilineInput::default();
        left_controls_flex.set_size(&subquote2, 70);

        left_controls_flex.set_size(
            &Frame::default()
                .with_label("Tag:")
                .with_align(enums::Align::Left | enums::Align::Inside),
            25,
        );
        let tag = Input::default();
        left_controls_flex.set_size(&tag, 30);

        left_controls_flex.set_size(
            &Frame::default()
                .with_label("Tag 2:")
                .with_align(enums::Align::Left | enums::Align::Inside),
            25,
        );
        let tag2 = Input::default();
        left_controls_flex.set_size(&tag2, 30);

        let mut actions_flex = Flex::default().row();
        Frame::default();
        let delete_btn = Button::default().with_label("Delete");
        actions_flex.set_size(&delete_btn, 100);
        let clone_btn = Button::default().with_label("Clone");
        actions_flex.set_size(&clone_btn, 100);
        let crop_btn = Button::default().with_label("Crop");
        actions_flex.set_size(&crop_btn, 100);
        Frame::default();
        actions_flex.end();
        left_controls_flex.set_size(&actions_flex, 30);

        Frame::default();

        let info_flex = Flex::default().row();
        let count = Frame::default().with_align(enums::Align::Left | enums::Align::Inside);
        let status = Frame::default();
        let dimension = Frame::default().with_align(enums::Align::Right | enums::Align::Inside);
        info_flex.end();
        left_controls_flex.set_size(&info_flex, 30);

        left_controls_flex.end();
        workspace_flex.set_size(&left_controls_flex, 310);

        // Page
        let mut center_row_flex = Flex::default().row();
        Frame::default();
        let mut center_col_flex = Flex::default().column();
        Frame::default();
        let img_view = Frame::default();
        center_col_flex.set_size(&img_view, 500);
        Frame::default();
        center_col_flex.end();
        Frame::default();
        center_row_flex.set_size(&center_col_flex, 400);
        center_row_flex.end();

        // Controls right
        let mut right_controls_flex = Flex::default().column();
        let mut translucent_layer_head_flex = Flex::default().row();
        Frame::default()
            .with_label("Translucent Layer:")
            .with_align(enums::Align::Left | enums::Align::Inside);
        let mut reset_darklayer_btn = Button::default();
        reset_darklayer_btn.set_image(Some(reload_image.clone()));
        translucent_layer_head_flex.set_size(&reset_darklayer_btn, 30);
        translucent_layer_head_flex.end();
        right_controls_flex.set_size(&translucent_layer_head_flex, 30);

        let mut translucent_layer_flex = Flex::default().row();
        translucent_layer_flex.set_pad(2);
        translucent_layer_flex.set_size(&Frame::default().with_label("Colour"), 50);
        let mut translucent_layer_rgb = Button::default();
        translucent_layer_rgb.set_frame(enums::FrameType::BorderBox);

        translucent_layer_flex.set_size(&Frame::default().with_label("Alpha"), 50);
        let mut translucent_layer_alpha = Spinner::default();
        translucent_layer_alpha.set_range(0.0, 255.0);
        translucent_layer_flex.end();
        right_controls_flex.set_size(&translucent_layer_flex, 30);

        let mut quote_position_flex = Flex::default().row();
        quote_position_flex.set_size(
            &Frame::default()
                .with_label("Quote Position")
                .with_align(enums::Align::Left | enums::Align::Inside),
            140,
        );
        let quote_position = fltk::misc::Spinner::default();
        let mut reset_quote_position_btn = Button::default();
        reset_quote_position_btn.set_image(Some(reload_image.clone()));
        quote_position_flex.set_size(&reset_quote_position_btn, 30);
        quote_position_flex.end();
        right_controls_flex.set_size(&quote_position_flex, 30);

        let mut quote_position_slider = Slider::default().with_type(SliderType::HorizontalNice);
        quote_position_slider.set_step(1.0, 1);
        quote_position_slider.set_frame(enums::FrameType::NoBox);
        right_controls_flex.set_size(&quote_position_slider, 30);

        let mut subquote_position_flex = Flex::default().row();
        subquote_position_flex.set_size(
            &Frame::default()
                .with_label("Subquote Position")
                .with_align(enums::Align::Left | enums::Align::Inside),
            140,
        );
        let subquote_position = fltk::misc::Spinner::default();
        let mut reset_subquote_position_btn = Button::default();
        reset_subquote_position_btn.set_image(Some(reload_image.clone()));
        subquote_position_flex.set_size(&reset_subquote_position_btn, 30);
        subquote_position_flex.end();
        right_controls_flex.set_size(&subquote_position_flex, 30);

        let mut subquote_position_slider = Slider::default().with_type(SliderType::HorizontalNice);
        subquote_position_slider.set_step(1.0, 1);
        subquote_position_slider.set_frame(enums::FrameType::NoBox);
        right_controls_flex.set_size(&subquote_position_slider, 30);

        let mut subquote2_position_flex = Flex::default().row();
        subquote2_position_flex.set_size(
            &Frame::default()
                .with_label("Subquote 2 Position")
                .with_align(enums::Align::Left | enums::Align::Inside),
            140,
        );
        let subquote2_position = fltk::misc::Spinner::default();
        let mut reset_subquote2_position_btn = Button::default();
        reset_subquote2_position_btn.set_image(Some(reload_image.clone()));
        subquote2_position_flex.set_size(&reset_subquote2_position_btn, 30);
        subquote2_position_flex.end();
        right_controls_flex.set_size(&subquote2_position_flex, 30);

        let mut subquote2_position_slider = Slider::default().with_type(SliderType::HorizontalNice);
        subquote2_position_slider.set_step(1.0, 1);
        subquote2_position_slider.set_frame(enums::FrameType::NoBox);
        right_controls_flex.set_size(&subquote2_position_slider, 30);

        let mut tag_position_flex = Flex::default().row();
        tag_position_flex.set_size(
            &Frame::default()
                .with_label("Tag Position")
                .with_align(enums::Align::Left | enums::Align::Inside),
            140,
        );
        let tag_position = fltk::misc::Spinner::default();
        let mut reset_tag_position_btn = Button::default();
        reset_tag_position_btn.set_image(Some(reload_image.clone()));
        tag_position_flex.set_size(&reset_tag_position_btn, 30);
        tag_position_flex.end();
        right_controls_flex.set_size(&tag_position_flex, 30);

        let mut tag_position_slider = Slider::default().with_type(SliderType::HorizontalNice);
        tag_position_slider.set_step(1.0, 1);
        tag_position_slider.set_frame(enums::FrameType::NoBox);
        right_controls_flex.set_size(&tag_position_slider, 30);

        let mut tag2_position_flex = Flex::default().row();
        tag2_position_flex.set_size(
            &Frame::default()
                .with_label("Tag 2 Position")
                .with_align(enums::Align::Left | enums::Align::Inside),
            140,
        );
        let tag2_position = fltk::misc::Spinner::default();
        let mut reset_tag2_position_btn = Button::default();
        reset_tag2_position_btn.set_image(Some(reload_image.clone()));
        tag2_position_flex.set_size(&reset_tag2_position_btn, 30);
        tag2_position_flex.end();
        right_controls_flex.set_size(&tag2_position_flex, 30);

        let mut tag2_position_slider = Slider::default().with_type(SliderType::HorizontalNice);
        tag2_position_slider.set_step(1.0, 1);
        tag2_position_slider.set_frame(enums::FrameType::NoBox);
        right_controls_flex.set_size(&tag2_position_slider, 30);

        Frame::default();
        right_controls_flex.end();
        workspace_flex.set_size(&right_controls_flex, 270);

        workspace_flex.end();

        main_flex.end();

        win.end();
        win.make_resizable(true);
        win.show();

        let properties = Arc::new(RwLock::new(ImageProperties::default()));
        let (rx, tx) = std::sync::mpsc::channel();
        let mut main_win = Self {
            win,
            menubar,
            back_btn,
            next_btn,
            save_btn,
            file_choice,
            quote,
            subquote,
            subquote2,
            tag,
            tag2,
            translucent_layer_rgb,
            translucent_layer_alpha,
            quote_position,
            subquote_position,
            subquote2_position,
            tag_position,
            tag2_position,
            quote_position_slider,
            subquote_position_slider,
            subquote2_position_slider,
            tag_position_slider,
            tag2_position_slider,
            reset_translucent_layer_btn: reset_darklayer_btn,
            reset_quote_position_btn,
            reset_subquote_position_btn,
            reset_subquote2_position_btn,
            reset_tag_position_btn,
            reset_tag2_position_btn,
            reset_file_choice,
            crop_btn,
            clone_btn,
            delete_btn,
            status,
            count,
            dimension,
            images_path: Arc::new(RwLock::new(vec![])),
            draw_buff,
            properties: Arc::clone(&properties),
            page: Page {
                image: img_view,
                row_flex: center_row_flex,
                col_flex: center_col_flex,
            },
            sender: rx,
        };
        spawn_image_thread(tx, sender, Arc::clone(&properties), &main_win);
        main_win.menu();
        main_win.draw();
        main_win.events();
        main_win
    }

    /// Set menubar in window
    fn menu(&mut self) {
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        let imgs = Arc::clone(&self.images_path);
        self.menubar.add(
            "&File/Open Folder...\t",
            Shortcut::Ctrl | 'o',
            menu::MenuFlag::Normal,
            move |_| {
                let mut chooser = NativeFileChooser::new(fltk::dialog::FileDialogType::BrowseDir);
                chooser.set_option(fltk::dialog::FileDialogOptions::NewFolder);
                chooser.show();
                let path = chooser.filename();
                let path = fs::canonicalize(&path).unwrap_or(path);
                if !path.exists() {
                    return;
                }
                let expost_dir = path.join("export");
                if !expost_dir.exists() {
                    if let Err(e) = fs::create_dir(expost_dir) {
                        fltk::dialog::alert_default("Failed to create export folder!");
                        warn!("Failed to create export folder!\n{:?}", e);
                        return;
                    }
                }
                load_dir(&path, Arc::clone(&imgs), &mut file_choice, &sender);
            },
        );

        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.menubar.add(
            "&File/Save...\t",
            Shortcut::Ctrl | 's',
            menu::MenuFlag::Normal,
            move |_| {
                let mut prop = properties.write().unwrap();
                prop.is_saved = true;
                sender.send(DrawMessage::Save).unwrap();
            },
        );

        let mut config_window = ConfigWindow::new();
        let sender = self.sender.clone();
        let mut image = self.page.image.clone();
        self.menubar.add(
            "&Edit/Configure...\t",
            Shortcut::None,
            menu::MenuFlag::Normal,
            move |_| {
                if config_window.show() {
                    sender.send(DrawMessage::RedrawToBuffer).unwrap();
                    sender.send(DrawMessage::Flush).unwrap();
                    image.redraw();
                }
            },
        );

        let mut about_win = About::new();
        self.menubar.add(
            "&Help/About...\t",
            Shortcut::None,
            menu::MenuFlag::Normal,
            move |_| {
                about_win.show();
            },
        );
    }

    /// Set drawing in window
    fn draw(&mut self) {
        let buff = Arc::clone(&self.draw_buff);
        let properties = Arc::clone(&self.properties);
        self.page.image.draw(move |f| {
            let (width, height) = properties.read().unwrap().dimension;
            if let Some(image) = &*buff.read().unwrap() {
                dr::draw_image(
                    &image,
                    f.x(),
                    f.y(),
                    width as i32,
                    height as i32,
                    enums::ColorDepth::Rgb8,
                )
                .unwrap();
            }
        })
    }

    /// Set callbacks of elements
    fn events(&mut self) {
        // Resest Button for FileChoice
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        let imgs = Arc::clone(&self.images_path);
        self.reset_file_choice.set_callback(move |_| {
            let path = match imgs.read().unwrap().first() {
                Some(path) => path.parent().unwrap().to_path_buf(),
                None => return,
            };
            load_dir(&path, Arc::clone(&imgs), &mut file_choice, &sender);
        });

        // Reset Button for Translucent Layer
        let mut layer_rgb = self.translucent_layer_rgb.clone();
        let mut layer_alpha = self.translucent_layer_alpha.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_translucent_layer_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let color = globals::CONFIG.read().unwrap().color_layer;
            prop.translucent_layer_color = color;
            prop.is_saved = false;
            utils::set_color_btn_rgba(color, &mut layer_rgb);
            layer_alpha.set_value(color[3] as f64);
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Reset Button for Quote Input
        let mut quote_position = self.quote_position.clone();
        let mut quote_position_slider = self.quote_position_slider.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_quote_position_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let height = prop.original_dimension.1;
            let pos = height * globals::CONFIG.read().unwrap().quote_position_ratio;
            prop.quote_position = pos;
            prop.is_saved = false;
            quote_position.set_value(pos);
            quote_position_slider.set_value(pos);

            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Reset Button for Subquote Input
        let mut subquote_position = self.subquote_position.clone();
        let mut subquote_position_slider = self.subquote_position_slider.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_subquote_position_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let height = prop.original_dimension.1;
            let pos = height * globals::CONFIG.read().unwrap().subquote_position_ratio;
            prop.subquote_position = pos;
            prop.is_saved = false;
            subquote_position.set_value(pos);
            subquote_position_slider.set_value(pos);

            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Reset Button for Subquotes2 Input
        let mut subquote2_position = self.subquote2_position.clone();
        let mut subquote2_position_slider = self.subquote2_position_slider.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_subquote2_position_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let height = prop.original_dimension.1;
            let pos = height * globals::CONFIG.read().unwrap().subquote2_position_ratio;
            prop.subquote2_position = pos;
            prop.is_saved = false;
            subquote2_position.set_value(pos);
            subquote2_position_slider.set_value(pos);

            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Reset Button for Tag Input
        let mut tag_position = self.tag_position.clone();
        let mut tag_position_slider = self.tag_position_slider.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_tag_position_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let height = prop.original_dimension.1;
            let pos = height * globals::CONFIG.read().unwrap().tag_position_ratio;
            prop.tag_position = pos;
            prop.is_saved = false;
            tag_position.set_value(pos);
            tag_position_slider.set_value(pos);

            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Reset Button for Tag2 Input
        let mut tag2_position = self.tag2_position.clone();
        let mut tag2_position_slider = self.tag2_position_slider.clone();
        let mut image = self.page.image.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.reset_tag2_position_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            let height = prop.original_dimension.1;
            let pos = height * globals::CONFIG.read().unwrap().tag2_position_ratio;
            prop.tag2_position = pos;
            prop.is_saved = false;
            tag2_position.set_value(pos);
            tag2_position_slider.set_value(pos);

            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Save Button
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.save_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            prop.is_saved = true;
            sender.send(DrawMessage::Save).unwrap()
        });

        // Clone Button
        let mut image = self.page.image.clone();
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        self.clone_btn.set_callback(move |_| {
            let ch = dialog::choice_default("Do you want to clone??", "Yes", "No", "");
            if ch == 0 {
                sender.send(DrawMessage::Clone).unwrap();
                sender.send(DrawMessage::Open).unwrap();
                image.redraw();
                file_choice.redraw();
            }
        });

        // Delete Button
        let mut image = self.page.image.clone();
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        self.delete_btn.set_callback(move |_| {
            let ch = dialog::choice_default("Do you want to delete??", "Yes", "No", "");
            if ch == 0 {
                sender.send(DrawMessage::Delete).unwrap();
                sender.send(DrawMessage::Open).unwrap();
                image.redraw();
                file_choice.redraw();
            }
        });

        // Crop Button
        let properties = Arc::clone(&self.properties);
        let mut crop_win = CropWindow::new();
        let sender = self.sender.clone();
        self.crop_btn.set_callback(move |_| {
            let mut prop = properties.write().unwrap();
            if let Some(path) = &prop.path {
                if let Some((x, y)) = crop_win.load_to_crop(path, prop.crop_position) {
                    sender.send(DrawMessage::ChangeCrop((x, y))).unwrap();
                    prop.is_saved = false;
                }
            }
        });

        // Next Image Button
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.next_btn.set_callback(move |_| {
            let prop = properties.read().unwrap();
            if !prop.is_saved {
                let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
                match save {
                    0 => sender.send(DrawMessage::Save).unwrap(),
                    1 => {}
                    _ => return,
                }
            }

            if file_choice.value() == file_choice.size() - 2 {
                file_choice.set_value(0);
            } else {
                file_choice.set_value(file_choice.value() + 1);
            }
            sender.send(DrawMessage::Open).unwrap();
        });

        // Back Image Button
        let mut file_choice = self.file_choice.clone();
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.back_btn.set_callback(move |_| {
            let prop = properties.read().unwrap();
            if !prop.is_saved {
                let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
                match save {
                    0 => sender.send(DrawMessage::Save).unwrap(),
                    1 => {}
                    _ => return,
                }
            }

            if file_choice.value() == 0 {
                file_choice.set_value(file_choice.size() - 2);
            } else {
                file_choice.set_value(file_choice.value() - 1);
            }
            sender.send(DrawMessage::Open).unwrap();
        });

        // File Choice
        let sender = self.sender.clone();
        let properties = Arc::clone(&self.properties);
        self.file_choice.set_callback(move |_| {
            let prop = properties.read().unwrap();
            if !prop.is_saved {
                let save = fltk::dialog::choice_default("Save?", "yes", "no", "cancel");
                match save {
                    0 => sender.send(DrawMessage::Save).unwrap(),
                    1 => {}
                    _ => return,
                }
            }
            sender.send(DrawMessage::Open).unwrap();
        });

        // Quote Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.quote.handle(move |f, ev| {
            if ev == enums::Event::KeyUp {
                let mut prop = properties.write().unwrap();
                prop.quote = f.value();
                prop.is_saved = false;
                sender.send(DrawMessage::RedrawToBuffer).unwrap();
                sender.send(DrawMessage::Flush).unwrap();
                image.redraw();
            }
            true
        });

        // Subquote Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.subquote.handle(move |f, ev| {
            if ev == enums::Event::KeyUp {
                let mut prop = properties.write().unwrap();
                prop.subquote = f.value();
                prop.is_saved = false;
                sender.send(DrawMessage::RedrawToBuffer).unwrap();
                sender.send(DrawMessage::Flush).unwrap();
                image.redraw();
            }
            true
        });

        // Subquote2 Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.subquote2.handle(move |f, ev| {
            if ev == enums::Event::KeyUp {
                let mut prop = properties.write().unwrap();
                prop.subquote2 = f.value();
                prop.is_saved = false;
                sender.send(DrawMessage::RedrawToBuffer).unwrap();
                sender.send(DrawMessage::Flush).unwrap();
                image.redraw();
            }
            true
        });

        // Tag Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.tag.handle(move |f, ev| {
            if ev == enums::Event::KeyUp {
                let mut prop = properties.write().unwrap();
                prop.tag = f.value();
                prop.is_saved = false;
                sender.send(DrawMessage::RedrawToBuffer).unwrap();
                sender.send(DrawMessage::Flush).unwrap();
                image.redraw();
            }
            true
        });

        // Tag2 Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.tag2.handle(move |f, ev| {
            if ev == enums::Event::KeyUp {
                let mut prop = properties.write().unwrap();
                prop.tag2 = f.value();
                prop.is_saved = false;
                sender.send(DrawMessage::RedrawToBuffer).unwrap();
                sender.send(DrawMessage::Flush).unwrap();
                image.redraw();
            }
            true
        });

        // Quote Position Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut quote_position_slider = self.quote_position_slider.clone();
        self.quote_position.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.quote_position = f.value();
            quote_position_slider.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Quote Position Slider
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut quote_position = self.quote_position.clone();
        self.quote_position_slider.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.quote_position = f.value();
            quote_position.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Subquote Position Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut subquote_position_slider = self.subquote_position_slider.clone();
        self.subquote_position.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.subquote_position = f.value();
            subquote_position_slider.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Subquote Position Slider
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut subquote_position = self.subquote_position.clone();
        self.subquote_position_slider.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.subquote_position = f.value();
            subquote_position.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Subquote2 Position Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut subquote2_position_slider = self.subquote2_position_slider.clone();
        self.subquote2_position.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.subquote2_position = f.value();
            subquote2_position_slider.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Subquote2 Position Slider
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut subquote2_position = self.subquote2_position.clone();
        self.subquote2_position_slider.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.subquote2_position = f.value();
            subquote2_position.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Tag Position Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut tag_position_slider = self.tag_position_slider.clone();
        self.tag_position.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.tag_position = f.value();
            tag_position_slider.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Tag Position Slider
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut tag_position = self.tag_position.clone();
        self.tag_position_slider.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.tag_position = f.value();
            tag_position.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Tag2 Position Input
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut tag2_position_slider = self.tag2_position_slider.clone();
        self.tag2_position.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.tag2_position = f.value();
            tag2_position_slider.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Tag2 Position Slider
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        let mut tag2_position = self.tag2_position.clone();
        self.tag2_position_slider.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.tag2_position = f.value();
            tag2_position.set_value(f.value());
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Translucent Layer RGB
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.translucent_layer_rgb.set_callback(move |mut f| {
            let mut prop = properties.write().unwrap();
            let (r, g, b) = dialog::color_chooser_with_default(
                "Pick a colour",
                dialog::ColorMode::Byte,
                (
                    prop.translucent_layer_color[0],
                    prop.translucent_layer_color[1],
                    prop.translucent_layer_color[2],
                ),
            );
            prop.translucent_layer_color = [r, g, b, prop.translucent_layer_color[3]];
            utils::set_color_btn_rgba(prop.translucent_layer_color, &mut f);
            f.redraw();
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });

        // Translucent Layer Opacity
        let mut image = self.page.image.clone();
        let properties = Arc::clone(&self.properties);
        let sender = self.sender.clone();
        self.translucent_layer_alpha.set_callback(move |f| {
            let mut prop = properties.write().unwrap();
            prop.translucent_layer_color[3] = f.value() as u8;
            prop.is_saved = false;
            sender.send(DrawMessage::RedrawToBuffer).unwrap();
            sender.send(DrawMessage::Flush).unwrap();
            image.redraw();
        });
    }
}

/// Load all iamges in a directory
fn load_dir(
    path: &PathBuf,
    imgs: Arc<RwLock<Vec<PathBuf>>>,
    file_choice: &mut menu::Choice,
    sender: &mpsc::Sender<DrawMessage>,
) {
    let mut files = fs::read_dir(path)
        .unwrap()
        .map(|r| r.unwrap())
        .collect::<Vec<fs::DirEntry>>();
    files.sort_by_key(|i| i.file_name());
    let mut text = String::new();
    let mut imgs_b = imgs.write().unwrap();
    *imgs_b = vec![];
    for file in files {
        let path = file.path();
        if path.extension() == Some(OsStr::new("jpg"))
            || path.extension() == Some(OsStr::new("png"))
        {
            text = format!("{}|{}", text, path.file_name().unwrap().to_str().unwrap());
            imgs_b.push(path);
        }
    }
    if text.len() == 0 {
        return;
    }
    file_choice.clear();
    file_choice.add_choice(&text[1..]);
    file_choice.set_value(0);
    sender.send(DrawMessage::Open).unwrap();
}
