// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#![allow(dead_code)]
use {
    crate::ui::terminal_views::{GridView, ScrollBar},
    carnelian::{
        color::Color,
        input::{self},
        render::{Composition, Context as RenderContext, PreClear, RenderExt},
        Coord, Rect, Size, ViewAssistantContext,
    },
    fuchsia_trace as ftrace,
    term_model::term::RenderableCellsIter,
};

pub struct TerminalScene {
    composition: Composition,
    background_color: Color,
    grid_view: GridView,
    scroll_bar: ScrollBar,
    size: Size,
    scroll_context: ScrollContext,
}

const SCROLL_BAR_WIDTH: f32 = 16.0;

pub enum PointerEventResponse {
    /// Indicates that the pointer event resulted in the user wanting to scroll the grid
    ScrollLines(isize),

    /// Indicates that there are no changes in the grid but the view needs to be updated.
    /// This is usually in response to the scroll bar scrolling but not changing the lines.
    ViewDirty,
}

impl TerminalScene {
    pub fn new(background_color: Color) -> TerminalScene {
        let composition = Composition::new(background_color);
        TerminalScene { background_color, composition, ..TerminalScene::default() }
    }

    pub fn update_background_color(&mut self, new_color: Color) {
        self.background_color = new_color;
    }

    pub fn calculate_term_size_from_size(size: &Size) -> Size {
        Size::new(size.width - SCROLL_BAR_WIDTH, size.height)
    }

    pub fn render<'a, C>(
        &mut self,
        render_context: &mut RenderContext,
        context: &ViewAssistantContext,
        cells: RenderableCellsIter<'a, C>,
    ) {
        ftrace::duration!("terminal", "Scene:TerminalScene:render2");
        let image = render_context.get_current_image(context);
        let ext = RenderExt {
            pre_clear: Some(PreClear { color: self.background_color }),
            ..Default::default()
        };

        let grid_layers = self.grid_view.render(render_context, cells);
        let scroll_bar_layers = self.scroll_bar.render(render_context);

        self.composition.replace(.., grid_layers.into_iter().chain(scroll_bar_layers));

        render_context.render(&self.composition, None, image, &ext);
    }

    pub fn update_size(&mut self, new_size: Size, cell_size: Size) {
        ftrace::duration!("terminal", "Scene:TerminalScene:update_size");

        self.grid_view.cell_size = cell_size;
        self.size = new_size;

        self.grid_view.frame =
            Rect::from_size(TerminalScene::calculate_term_size_from_size(&new_size));

        let mut scroll_bar_frame = Rect::from_size(new_size);
        scroll_bar_frame.size.width = SCROLL_BAR_WIDTH;
        scroll_bar_frame.origin.x = new_size.width - SCROLL_BAR_WIDTH;
        self.scroll_bar.frame = scroll_bar_frame;

        self.update_scroll_metrics();
    }

    pub fn update_scroll_context(&mut self, scroll_context: ScrollContext) {
        if scroll_context != self.scroll_context {
            self.scroll_context = scroll_context;
            self.update_scroll_metrics();
        }
    }

    pub fn handle_pointer_event(
        &mut self,
        event: &input::pointer::Event,
        _ctx: &mut ViewAssistantContext,
    ) -> Option<PointerEventResponse> {
        if self.scroll_bar.is_tracking() {
            return self.handle_primary_pointer_event_for_scroll_bar(&event);
        } else {
            match event.phase {
                input::pointer::Phase::Down(point) => {
                    let point = point.to_f32();
                    if self.scroll_bar.frame.contains(point) {
                        return self.handle_primary_pointer_event_for_scroll_bar(&event);
                    }
                }
                _ => (),
            }
        }

        None
    }

    fn update_scroll_metrics(&mut self) {
        let total_lines = self.scroll_context.history + self.scroll_context.visible_lines;
        let content_height = self.grid_view.cell_size.height * (total_lines as Coord);

        let content_offset =
            self.grid_view.cell_size.height * (self.scroll_context.display_offset as Coord);

        self.scroll_bar.content_height = content_height;
        self.scroll_bar.content_offset = content_offset;
        self.scroll_bar.invalidate_thumb_frame();
    }

    fn handle_primary_pointer_event_for_scroll_bar(
        &mut self,
        event: &input::pointer::Event,
    ) -> Option<PointerEventResponse> {
        // The following logic assumes that we are only tracking one pointer at a time.
        let prev_offset = self.scroll_bar.content_offset;
        match event.phase {
            input::pointer::Phase::Down(location) => {
                self.scroll_bar.begin_tracking_pointer_event(location.to_f32());
            }
            input::pointer::Phase::Moved(location) => {
                self.scroll_bar.handle_pointer_move(location.to_f32())
            }
            input::pointer::Phase::Up
            | input::pointer::Phase::Remove
            | input::pointer::Phase::Cancel => self.scroll_bar.cancel_pointer_event(),
        };

        // do not rely on the ScrollContext being udpated at this point. Rely on the
        // values stored in the scroll bar to determine how many rows we have changed.
        let offset_change = Self::calculate_change_in_scroll_offset(
            prev_offset,
            self.scroll_bar.content_offset,
            self.grid_view.cell_size.height,
        );

        match offset_change {
            0 => Some(PointerEventResponse::ViewDirty),
            _ => Some(PointerEventResponse::ScrollLines(offset_change)),
        }
    }

    fn calculate_change_in_scroll_offset(
        previous_content_offset: f32,
        content_offset: f32,
        row_height: f32,
    ) -> isize {
        let new_row = f32::floor(content_offset / row_height);
        let old_row = f32::floor(previous_content_offset / row_height);
        (new_row - old_row) as isize
    }
}

impl Default for TerminalScene {
    fn default() -> Self {
        let background_color = Color::new();
        let composition = Composition::new(background_color);
        TerminalScene {
            composition,
            background_color,
            size: Size::zero(),
            grid_view: GridView::new(&background_color),
            scroll_bar: ScrollBar::default(),
            scroll_context: ScrollContext::default(),
        }
    }
}

#[derive(Eq, PartialEq)]
pub struct ScrollContext {
    pub history: usize,
    pub visible_lines: usize,
    pub display_offset: usize,
}

impl Default for ScrollContext {
    fn default() -> Self {
        ScrollContext { history: 0, visible_lines: 0, display_offset: 0 }
    }
}

#[cfg(test)]
mod tests {
    use {super::*, carnelian::Point};

    #[test]
    fn calculate_difference_in_display_offset_no_change() {
        let row_height = 10.0;
        let content_offset = 10.1;
        let prev_offset = 10.0;

        // jump from row 1 to row 1
        let delta = TerminalScene::calculate_change_in_scroll_offset(
            prev_offset,
            content_offset,
            row_height,
        );
        assert_eq!(delta, 0);
    }

    #[test]
    fn calculate_difference_in_display_offset_single_line() {
        let row_height = 10.0;
        let content_offset = 20.1;
        let prev_offset = 10.0;

        // jump from row 1 to row 2
        let delta = TerminalScene::calculate_change_in_scroll_offset(
            prev_offset,
            content_offset,
            row_height,
        );
        assert_eq!(delta, 1);
    }

    #[test]
    fn calculate_difference_in_display_offset_down_single_line() {
        let row_height = 10.0;
        let content_offset = 19.0;
        let prev_offset = 20.0;

        // jump from row 2 to row 1
        let delta = TerminalScene::calculate_change_in_scroll_offset(
            prev_offset,
            content_offset,
            row_height,
        );
        assert_eq!(delta, -1);
    }

    #[test]
    fn calculate_difference_in_display_offset_multiple_lines() {
        let row_height = 10.0;
        let content_offset = 25.0;
        let prev_offset = 0.0;

        // jump from row 0 to row 2
        let delta = TerminalScene::calculate_change_in_scroll_offset(
            prev_offset,
            content_offset,
            row_height,
        );
        assert_eq!(delta, 2);
    }

    #[test]
    fn new_with_color_sets_background_color() {
        let scene = TerminalScene::new(Color { r: 255, ..Color::new() });
        assert_eq!(scene.background_color.r, 255);
    }

    #[test]
    fn update_background_color_sets_color_of_bg_view() {
        let mut scene = TerminalScene::default();
        scene.update_background_color(Color { g: 255, ..Color::new() });
        assert_eq!(scene.background_color.g, 255);
    }

    #[test]
    fn update_cell_size_updates_grid_view() {
        let mut scene = TerminalScene::default();
        scene.update_size(Size::zero(), Size::new(99.0, 99.0));
        assert_eq!(scene.grid_view.cell_size, Size::new(99.0, 99.0));
    }

    #[test]
    fn calculate_term_size_has_affordance_for_scroll_bar() {
        let size = Size::new(100.0, 100.0);
        let calculated = TerminalScene::calculate_term_size_from_size(&size);

        assert_eq!(calculated.width, 84.0);
        assert_eq!(calculated.height, 100.0);
    }

    #[test]
    fn update_size_sets_frames() {
        let mut scene = TerminalScene::default();
        let size = Size::new(100.0, 100.0);
        scene.update_size(size, Size::zero());

        assert_eq!(scene.grid_view.frame, Rect::new(Point::zero(), Size::new(84.0, 100.0)));
        assert_eq!(
            scene.scroll_bar.frame,
            Rect::new(Point::new(84.0, 0.0), Size::new(16.0, 100.0))
        );
    }

    #[test]
    fn update_scroll_context_updates_content_height() {
        let mut scene = TerminalScene::default();
        scene.update_size(Size::zero(), Size::new(10.0, 10.0));
        assert_eq!(scene.scroll_bar.content_height, 0.0);

        let scroll_context = ScrollContext { history: 300, visible_lines: 2, display_offset: 0 };

        scene.update_scroll_context(scroll_context);
        assert_eq!(scene.scroll_bar.content_height, 3020.0);
    }

    #[test]
    fn update_scroll_context_updates_content_offset() {
        let mut scene = TerminalScene::default();
        scene.update_size(Size::zero(), Size::new(10.0, 10.0));
        let scroll_context = ScrollContext { history: 300, visible_lines: 2, display_offset: 10 };

        scene.update_scroll_context(scroll_context);
        assert_eq!(scene.scroll_bar.content_offset, 100.0);
    }

    #[test]
    fn update_cell_size_updates_content_size() {
        let mut scene = TerminalScene::default();

        let scroll_context = ScrollContext { history: 300, visible_lines: 2, display_offset: 0 };

        scene.update_scroll_context(scroll_context);

        scene.update_size(Size::zero(), Size::new(10.0, 5.0));
        assert_eq!(scene.scroll_bar.content_height, 1510.0);
    }

    #[test]
    fn update_cell_size_updates_content_offset() {
        let mut scene = TerminalScene::default();

        // originally frame is much bigger than content so there is no offset
        scene.update_size(Size::zero(), Size::new(10.0, 10.0));
        let scroll_context = ScrollContext { history: 10, visible_lines: 10, display_offset: 10 };
        scene.update_scroll_context(scroll_context);

        assert_eq!(scene.scroll_bar.content_offset, 100.0);

        scene.update_size(Size::new(100.0, 1000.0), Size::new(10.0, 5.0));
        assert_eq!(scene.scroll_bar.content_offset, 50.0);
    }
}
