Documentation
use std::sync::{Arc, Mutex};

use psdk_father::{
  args::{ArgContext, PsdkArgBase, PsdkEasyArg},
  command::CommandClause,
  errors::PsdkFatherResult,
};

use crate::marks::Mode;

#[derive(Clone, Debug)]
pub struct CPrintOptions {
  /// 旋转(默认不旋转)
  pub mode: Option<Mode>,
}

#[derive(Clone, Debug)]
pub struct CPrint {
  options: CPrintOptions,
  ctx: Arc<Mutex<ArgContext>>,
}

impl CPrint {
  pub fn new(options: CPrintOptions) -> Self {
    Self {
      options,
      ctx: Default::default(),
    }
  }
}

impl Default for CPrint {
  fn default() -> Self {
    Self::new(CPrintOptions { mode: None })
  }
}

impl From<Mode> for CPrint {
  fn from(mode: Mode) -> Self {
    Self::new(CPrintOptions { mode: Some(mode) })
  }
}

impl PsdkEasyArg<String> for CPrint {
  fn context(&self) -> Arc<Mutex<ArgContext>> {
    self.ctx.clone()
  }
}

impl PsdkArgBase<String> for CPrint {
  fn header(&self) -> String {
    match self.options.mode {
      Some(Mode::Normal) => "PRINT".to_string(),
      Some(Mode::Horizontal) => "POPRINT".to_string(),
      Some(Mode::Mirror) => "POPRINT".to_string(),
      None => "PRINT".to_string(),
    }
  }

  fn clause(&self) -> PsdkFatherResult<CommandClause> {
    Ok(CommandClause::with_text(self.header()))
  }
}

psdk_father::impl_psdk_arg_to_easy_arg!(String, CPrint, true);