<commit_before>use rustwlc::{Point, ResizeEdge};
use uuid::Uuid;
use petgraph::graph::NodeIndex;

use super::super::LayoutTree;
use super::super::commands::CommandResult;
use super::super::core::{Direction, ShiftDirection, TreeError};
use super::super::core::container::{Container, ContainerType, ContainerErr,
                                    Handle, Layout};

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum MovementError {
    /// Attempted to move the node behind the UUID in the given direction,
    /// which would cause it to leave its siblings.
    MoveOutsideSiblings(Uuid, Direction),
    /// There was a tree error, generally should abort operation and pass this
    /// up back through the caller.
    Tree(Box<TreeError>),
    /// Expected the view to be floating, but it was not
    NotFloating(NodeIndex)
}

impl From<ContainerErr> for MovementError {
    fn from(err: ContainerErr) -> MovementError {
        MovementError::Tree(Box::new(err.into()))
    }
}


impl LayoutTree {
    /// Will attempt to move the container at the UUID in the given direction.
    pub fn move_container(&mut self, uuid: Uuid, direction: Direction) -> CommandResult {
        let node_ix = try!(self.tree.lookup_id(uuid).ok_or(TreeError::NodeNotFound(uuid)));
        let old_parent_ix = try!(self.tree.parent_of(node_ix).map_err(|err| TreeError::PetGraph(err)));
        try!(self.move_recurse(node_ix, None, direction));
        if self.tree.can_remove_empty_parent(old_parent_ix) {
            try!(self.remove_container(old_parent_ix));
        }
        self.validate();
        Ok(())
    }

    /// Returns the new parent of the active container if the move succeeds,
    /// Otherwise it signals what error occurred in the tree.
    fn move_recurse(&mut self, node_to_move: NodeIndex, move_ancestor: Option<NodeIndex>,
                           direction: Direction) -> Result<NodeIndex, TreeError> {
        match self.tree[node_to_move].get_type() {
            ContainerType::View | ContainerType::Container => { /* continue */ },
            _ => return Err(TreeError::UuidWrongType(self.tree[node_to_move].get_id(),
                                                     vec!(ContainerType::View,
                                                          ContainerType::Container)))
        }
        let parent_ix = try!(
            match move_ancestor {
                Some(node) => self.tree.parent_of(node),
                None => self.tree.parent_of(node_to_move)
            }.map_err(|err| TreeError::PetGraph(err)));
        match self.tree[parent_ix] {
            Container::Container { layout, .. } =>  {
                match (layout, direction) {<commit_msg>Fix title bar when moving container<commit_after>use rustwlc::{Point, ResizeEdge};
use uuid::Uuid;
use petgraph::graph::NodeIndex;

use super::super::LayoutTree;
use super::super::commands::CommandResult;
use super::super::core::{Direction, ShiftDirection, TreeError};
use super::super::core::container::{Container, ContainerType, ContainerErr,
                                    Handle, Layout};

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum MovementError {
    /// Attempted to move the node behind the UUID in the given direction,
    /// which would cause it to leave its siblings.
    MoveOutsideSiblings(Uuid, Direction),
    /// There was a tree error, generally should abort operation and pass this
    /// up back through the caller.
    Tree(Box<TreeError>),
    /// Expected the view to be floating, but it was not
    NotFloating(NodeIndex)
}

impl From<ContainerErr> for MovementError {
    fn from(err: ContainerErr) -> MovementError {
        MovementError::Tree(Box::new(err.into()))
    }
}


impl LayoutTree {
    /// Will attempt to move the container at the UUID in the given direction.
    pub fn move_container(&mut self, uuid: Uuid, direction: Direction) -> CommandResult {
        let node_ix = self.tree.lookup_id(uuid)
            .ok_or(TreeError::NodeNotFound(uuid))?;
        let old_parent_ix = self.tree.parent_of(node_ix)
            .map_err(|err| TreeError::PetGraph(err))?;
        let new_parent_ix = self.move_recurse(node_ix, None, direction)?;
        if self.tree.can_remove_empty_parent(old_parent_ix) {
            self.remove_container(old_parent_ix)?;
        }
        // NOTE refresh node_ix because it probably moved.
        let node_ix = self.tree.lookup_id(uuid)
            .ok_or(TreeError::NodeNotFound(uuid))?;
        let draw_title = match self.tree[new_parent_ix].get_layout()? {
            Layout::Tabbed | Layout::Stacked => false,
            Layout::Horizontal | Layout::Vertical => true
        };
        match self.tree[node_ix] {
            Container::View { ref mut borders, .. } => {
                borders.as_mut().map(|b| b.draw_title = draw_title);
            },
            _ => {}
        }
        self.layout(new_parent_ix);
        self.tree[node_ix].draw_borders()?;
        self.validate();
        Ok(())
    }

    /// Returns the new parent of the active container if the move succeeds,
    /// Otherwise it signals what error occurred in the tree.
    fn move_recurse(&mut self, node_to_move: NodeIndex, move_ancestor: Option<NodeIndex>,
                           direction: Direction) -> Result<NodeIndex, TreeError> {
        match self.tree[node_to_move].get_type() {
            ContainerType::View | ContainerType::Container => { /* continue */ },
            _ => return Err(TreeError::UuidWrongType(self.tree[node_to_move].get_id(),
                                                     vec!(ContainerType::View,
                                                          ContainerType::Container)))
        }
        let parent_ix = try!(
            match move_ancestor {
                Some(node) => self.tree.parent_of(node),
                None => self.tree.parent_of(node_to_move)
            }.map_err(|err| TreeError::PetGraph(err)));
        match self.tree[parent_ix] {
            Container::Container { layout, .. } =>  {
                match (layout, direction) {
{'fraction_non_alphanumeric': 0.11784122792540024, 'fraction_numerical': 0.0, 'mean_word_length': 2.452991452991453, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2205988', 'n_tokens_mistral': 1677, 'n_tokens_neox': 1673, 'n_words': 413}