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

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

#[derive(Clone, Debug)]
pub struct TPutImageOptions {
  /// 图片起始x坐标
  pub x: i32,
  /// 图片起始y坐标
  pub y: i32,
  /// 图片文件名
  pub file_name: String,
}

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

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

impl<F: Into<String>> From<(i32, i32, F)> for TPutImage {
  fn from((x, y, file_name): (i32, i32, F)) -> Self {
    Self::new(TPutImageOptions {
      x,
      y,
      file_name: file_name.into(),
    })
  }
}

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

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

  fn clause(&self) -> PsdkFatherResult<CommandClause> {
    let mut ptc = PsdkTextCommand::with_header_format_tspl(self.header());
    ptc
      .append(self.options.x)
      .append(self.options.y)
      .append_with_quote(&self.options.file_name);
    Ok(ptc.clause())
  }
}

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