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

use crate::args::page_height::{CPageHeight, CPageHeightOptions};
use crate::args::page_width::{CPageWidth, CPageWidthOptions};
use psdk_father::{
  args::{ArgContext, PsdkArgBase, PsdkEasyArg},
  command::{CommandClause, PsdkTextCommand},
  errors::PsdkFatherResult,
};

#[derive(Clone, Debug)]
pub struct CPageOptions {
  /// 打印区域高度(单位dot)
  pub height: i32,
  /// 打印区域宽度(单位dot)
  pub width: i32,
  /// 打印份数(默认一份)
  pub copies: i32,
}

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

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

impl From<(i32, i32)> for CPage {
  fn from((height, width): (i32, i32)) -> Self {
    Self::new(CPageOptions {
      height,
      width,
      copies: 1,
    })
  }
}

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

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

  fn clause(&self) -> PsdkFatherResult<CommandClause> {
    let page_height = CPageHeight::new(CPageHeightOptions {
      height: self.options.height,
      copies: self.options.copies,
    });
    let page_width = CPageWidth::new(CPageWidthOptions {
      width: self.options.width,
    });
    self.prepend(&page_height).unwrap();
    self.append(&page_width).unwrap();
    let ptc = PsdkTextCommand::with_header_format_cpcl(self.header());
    Ok(ptc.clause())
  }
}

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