use crate::marks::Direction;
use psdk_father::args::{ArgContext, PsdkArgBase, PsdkEasyArg};
use psdk_father::command::{CommandClause, PsdkTextCommand};
use psdk_father::errors::PsdkFatherResult;
use psdk_father::types::psdk_types::PsdkPrinterCommandEnumValue;
use std::sync::{Arc, Mutex};

#[derive(Clone, Debug)]
pub struct TDirectionOptions {
  /// 打印方向
  pub direction: Direction,
  /// 是否镜像
  pub mirror: bool,
}

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

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

impl Default for TDirection {
  fn default() -> Self {
    Self::new(TDirectionOptions {
      direction: Direction::UpOut,
      mirror: false,
    })
  }
}

impl From<Direction> for TDirection {
  fn from(direction: Direction) -> Self {
    Self::new(TDirectionOptions {
      direction,
      mirror: false,
    })
  }
}

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

impl PsdkArgBase<String> for TDirection {
  fn header(&self) -> String {
    "DIRECTION".to_string()
  }

  fn clause(&self) -> PsdkFatherResult<CommandClause> {
    let mut ptc = PsdkTextCommand::with_header_format_tspl(self.header());
    ptc
      .append(self.options.direction.command_value())
      .append(if self.options.mirror { "1" } else { "0" });
    Ok(ptc.clause())
  }
}

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