//! This module provides the command enum.

use std::path::PathBuf;
use library::RepeatMode;

#[derive(Debug)]
/// The different commands that one can send to a server.
pub enum Command {
    /// Does nothing, used to get the status from the server.
    NoOp,
    /// Switches between playing and paused.
    PlayPause,
    /// Stops the current song.
    Stop,
    /// Goes to the next song.
    NextSong,
    /// Goes to the previous song, even if the current song has already started since a while.
    PreviousSong,
    /// Opens a song from a path.
    Song(PathBuf),
    /// Stops the server.
    StopServer,
    /// Changes the repeat mode.
    ChangeRepeatMode(RepeatMode),
    /// Goes to the next album.
    NextAlbum,
    /// Goes to the previous album.
    PreviousAlbum,
}

impl Command {
    /// Serializes a command to a byte array.
    pub fn to_u8(&self) -> [u8; 256] {
        let mut ret = [0; 256];
        ret[0] = match *self {
            Command::NoOp => 0,
            Command::PlayPause => 1,
            Command::Stop => 2,
            Command::NextSong => 3,
            Command::PreviousSong => 4,
            Command::Song(ref p) => {
                // Fill the rest of the array with the path
                let path = p.to_str().unwrap();
                for (i, c) in path.chars().enumerate() {
                    ret[i+1] = c as u8;
                }
                5
            },
            Command::StopServer => 6,
            Command::ChangeRepeatMode(RepeatMode::NoRepeat) => 7,
            Command::ChangeRepeatMode(RepeatMode::RepeatOne) => 8,
            Command::ChangeRepeatMode(RepeatMode::RepeatAll) => 9,
            Command::NextAlbum => 10,
            Command::PreviousAlbum => 11,
        };

        ret
    }

    /// Parses a byte array and returns the corresponding command.
    pub fn from(v: &[u8; 256]) -> Result<Command, ()> 

}


{
        match v[0] {
            0 => Ok(Command::NoOp),
            1 => Ok(Command::PlayPause),
            2 => Ok(Command::Stop),
            3 => Ok(Command::NextSong),
            4 => Ok(Command::PreviousSong),
            5 => {
                use std::iter::FromIterator;
                let mut iter = v[1..255].iter();
                let index = (iter.position(|&x| x == 0 ).unwrap()) as usize;
                let path = String::from_iter(v[1..index+1].iter().map(|x| *x as char));
                Ok(Command::Song(PathBuf::from(path)))
            },
            6 => Ok(Command::StopServer),
            7 => Ok(Command::ChangeRepeatMode(RepeatMode::NoRepeat)),
            8 => Ok(Command::ChangeRepeatMode(RepeatMode::RepeatOne)),
            9 => Ok(Command::ChangeRepeatMode(RepeatMode::RepeatAll)),
            10 => Ok(Command::NextAlbum),
            11 => Ok(Command::PreviousAlbum),
            _ => Err(()),
        }
    }