using System;
using System.Collections.Generic;
using System.Windows.Forms;
using CLIP.eForm.Consent.Common;
using System.Reflection;
using System.Threading;
using System.Xml;
using System.IO;
using System.ComponentModel;
using System.Configuration;
using System.Drawing;
using CLIP.eForm.Consent.UI.ConsentSvcRef;
using ClipSoft.eForm.Base.Dialog;

namespace CLIP.eForm.Consent.UI
{
  /// <summary>
  /// 동의서 관리 메인 컨트롤 클래스
  /// </summary>
  /// <remarks>
  /// <p>[설계자]</p>
  /// <p>  클립소프트 연구소 홍지철 (jchong@clipsoft.co.kr)</p>
  /// <p>[원본 작성자]</p>
  /// <p>  클립소프트 기술부 이창훈 (chlee@clipsoft.co.kr)</p>
  /// <p>[수정 작성자]</p>
  /// <p>  클립소프트 기술부 이인희</p>
  /// <p>----------------------------------------------------------------------------------------</p>
  /// <p>[HISTORY]</p>
  /// <p> 2015-07-30 : 최초작성</p>
  /// <p>----------------------------------------------------------------------------------------</p>
  /// </remarks>  
  public partial class ConsentMainControl : UserControl, IConsentMainCtrl, IConsentMain
  {
    private string currentFormGuid = string.Empty;
    private ConsentSvcRef.ConsentSvcSoapClient consentWebService;
    private HospitalSvcRef.HospitalSvcSoapClient hospitalWebService;
    //private IConsentMainForm _consentMainForm = null;   // AgentForm(리턴시 사용)

    [Browsable(false)]
    public ConsentSvcRef.ConsentSvcSoapClient ConsentWebService { get { return consentWebService; } }

    [Browsable(false)]
    public HospitalSvcRef.HospitalSvcSoapClient HospitalWebService { get { return hospitalWebService; } }

    public string PluginModuleName { get; set; }

    private Dictionary<string, string> outputDataDic = null;
    private Dictionary<string, object> processResultValues = new Dictionary<string, object>();
    public Dictionary<string, string> ConsentExecuteInfo { get; set; }
    public Dictionary<string, string> PluginExecuteInfo { get; set; }
    public Dictionary<string, object> ProcessResultValues { get { return processResultValues; } }
    public List<ConsentFormListVO> PrintInfoList { get; set; }

    public event EventHandler OnLoadPartControls;
    public event EventHandler OnResizeReviewConsent;
    public event EventHandler OnVisibleEFormControl;
    public event EventHandler OnInvisibleEFormControl;
    public event ProcessResultHandler ProcessResult;

    public delegate void ProcessResultHandler(string result);

    public object mCallParm = null;
    public bool printSaveStatus { get; set; }
    public int multiPrintPlanCnt { get; set; }
    public int multiPrintExecCnt { get; set; }
    public bool saveClickPoint { get; set; }    // true : 메인창, false : 듀얼뷰어창
    public bool checkAutoPrint { get; set; }    // true : 입실저장 자동출력, false : 수동출력

    private static bool startform = true;

    public int agentCallPrintCnt { get; set; }

    public int printConsentCount = 1;

    // 원무 서식 인증서 pass 여부
    // 경북대병원 dependency
    public bool shouldPassCertify = false;

    public static Dictionary<String, String> SETTING_DATA = new Dictionary<String, String>();

    /// <summary>
    /// Gets or sets the call parameter.
    /// </summary>
    /// <value>
    /// The call parameter.
    /// </value>
    object IConsentMainCtrl.CallParam
    {
      get
      {
        return mCallParm;
      }
      set
      {
        mCallParm = value;
      }
    }

    public List<Dictionary<string, object>> multiParams { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="ConsentMainControl"/> class.
    /// </summary>
    /// <param name="callParam">The call parameter.</param>
    public ConsentMainControl(object callParam)
    {
      //MessageBox.Show("Waiting");
      InitializeComponent();

      bool isMultiParams = false;
      ToolTip _toolTip = new ToolTip();
      _toolTip.AutoPopDelay = 5000;
      _toolTip.InitialDelay = 0;
      _toolTip.ReshowDelay = 0;
      _toolTip.ShowAlways = true;

      _toolTip.SetToolTip(this.btnHelp, "도움말");

      // 실행 정보 데이터셋 초기화
      ConsentExecuteInfo = new Dictionary<string, string> {
                { "dutinstcd", string.Empty },
                { "userNo", string.Empty },
                { "loginUserNo", string.Empty },
                { "userName", string.Empty },
                { "loginUserName", string.Empty },
                { "userDeptCd", string.Empty },
                { "userDeptName", string.Empty },
                { "patientNo", string.Empty },
                { "visitType", string.Empty },
                { "clnDept", string.Empty },
                { "clnDate", string.Empty },
                { "cretno", string.Empty },
                { "clnDxNm", string.Empty },
                { "opRsrvNo", string.Empty },
                { "useListView", string.Empty },
                { "patientListView", string.Empty },
                { "startFormCd", string.Empty },
                { "printAct", string.Empty },
                { "printList", string.Empty },
                { "formCd", string.Empty },
                { "ocrTag", string.Empty },
                { "tempSave", string.Empty },
                { "printYN", string.Empty },
                { "printCount", string.Empty },
                { "printIP", string.Empty },
                { "prntCnt", string.Empty },
                { "userIOFlag", "O" },
                { "sysInstNm", string.Empty },
                { "readOnly", string.Empty },
                { "SpecDoctorYN", string.Empty },
                { "ContStartDate", string.Empty },
                { "ContEndDate", string.Empty },
                { "RoomCapa", string.Empty },
                { "ContTelNo", string.Empty },
                { "ContStaff1Name", string.Empty },
                { "ContStaff2Name", string.Empty },
                { "ContStaff3Name", string.Empty },
                { "DeviceType", string.Empty },
                // 경대병원 태그 추가
                { "tag1", string.Empty },
                { "tag2", string.Empty },
                { "tag3", string.Empty },
                { "tag4", string.Empty },
                { "tag5", string.Empty },
                { "tag6", string.Empty },
                { "tag7", string.Empty },
                { "tag8", string.Empty },
                { "tag9", string.Empty },
                { "tag10", string.Empty },
                { "CardNo", string.Empty }
            };

      PluginExecuteInfo = new Dictionary<string, string>();

      //연속서식인지 구분하는 부분
      if ((callParam != null) && (callParam is Dictionary<string, object> result)) {
        if (result.ContainsKey("VERSION") && result["VERSION"].ToString().Equals("2.0")) {
          isMultiParams = true;
        }
      }

      if (isMultiParams) {
        //연속서식일 때

        //화면설정 정보는 전역변수에 할당하고 나머지 배열로 들어오는 정보들은 multiParams에 할당하여
        //동의서를 부를 때 하나씩 전역변수에 넣고 동의서를 부른다
        InitMultiParamSetting(callParam);
        SetWebServiceUrlAndTimeout();
        this.PluginModuleName = ConfigurationManager.AppSettings["UIPluginAssembly"];

        if (multiParams.Count > 0) {
          //연속서식의 첫번째 서식을 불러오기 위해 파라미터 배열의 가장 첫번째 데이터를 전역변수에 할당한다
          Dictionary<string, object> pageCountParam = ((Dictionary<string, object>)multiParams[multiParams.Count - 1]);
          if (pageCountParam.ContainsKey("PAGE_COUNT") && Int32.TryParse(pageCountParam["PAGE_COUNT"].ToString(), out int page)) {
            setConsentViewMultiParams(page);
          }
        }
      } else {
        //연속서식이 아닐 때
        // 넘겨받은 callParam 를 디코딩 한다
        InitParamSetting(callParam);

        SetWebServiceUrlAndTimeout();

        this.PluginModuleName = ConfigurationManager.AppSettings["UIPluginAssembly"];
      }
    }

    //private void SendKeyValueMessageToAdapter(int key, string message)
    //{
    //    _consentMainForm.SendKeyValueMessageToAdapter(key, message);
    //}


    /// <summary>
    /// Gets a value indicating whether this instance has vertical monitor.
    /// </summary>
    /// <value>
    ///   <c>true</c> if this instance has vertical monitor; otherwise, <c>false</c>.
    /// </value>
    public static bool HasVerticalMonitor
    {
      get
      {
        if (Screen.AllScreens.Length > 1)
        {
          foreach (Screen screen in Screen.AllScreens)
          {
            if (screen.Bounds.Width < screen.Bounds.Height)
            {
              return true;
            }
          }
        }
        return false;
      }
    }

    /// <summary>
    /// 수술 관련 동의서 호출 시 수술탭 확인 후 팝업 호출
    /// </summary>
    /// <param name="formCd"></param>
    public bool checkOperationDocument(string formCd)
    {
      var hardcd = consentWebService.checkOperationDocument(ConsentExecuteInfo["dutinstcd"], formCd);
      var retValue = true;

      if (!opPatientSelected && hardcd.Equals("Y"))
      {
        DialogResult result = MessageBox.Show("수술정보가 없습니다. 수술 동의서는 수술 Tab에서 서식 출력 바랍니다.\n수술 정보 없이 계속 진행하시겠습니까?", "확인", MessageBoxButtons.OKCancel);

        if (result != DialogResult.OK)
        {
          retValue = false;
        }
      }
      return retValue;
    }

    private bool opPatientSelected = false;

    public void setOpPatientSelected(bool value)
    {
      this.opPatientSelected = value;
    }

    /// <summary>
    /// 주어진 서버 이름으로 설정파일을 로딩 한다
    /// </summary>
    /// <param name="pServerName">로드 할 서버 설정 파일</param>
    /// <returns></returns>
    public static Dictionary<string, string> GetConfigDictionary(string pServerName)
    {

      Dictionary<string, string> result = new Dictionary<string, string>();

      /*
      XmlDocument configXml = new XmlDocument();
      configXml.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + string.Format("/CLIP.Consent.xml"));
      XmlNodeList addNodes = configXml.SelectNodes("configuration/settings/add");
      foreach (XmlNode xmlNode in addNodes) {
          if (xmlNode.Attributes["key"].InnerText == "serviceTarget") {
              serviceTarget = ((XmlCDataSection)xmlNode.ChildNodes[0]).InnerText;
          }
      }
      */

      XmlDocument configXml = new XmlDocument();
      configXml.Load(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + string.Format("/CLIP.Consent-{0}.xml", pServerName));
      XmlNodeList addNodes = configXml.SelectNodes("configuration/settings/add");
      foreach (XmlNode xmlNode in addNodes)
      {
        result.Add(xmlNode.Attributes["key"].InnerText, ((XmlCDataSection)xmlNode.ChildNodes[0]).InnerText);
      }

      return result;
    }

    /// <summary>
    /// childControl의 부모와 그의 부모들에서 IConsentMain 인터페이스를 구현하는 클래스를 찾는다.
    /// </summary>
    /// <param name="childControl"></param>
    /// <returns></returns>
    public static IConsentMain GetConsentMainInterface(Control childControl)
    {
      if (childControl.Parent == null)
      {
        return null;
      }
      else
      {
        if (childControl.Parent is IConsentMain)
        {
          return childControl.Parent as IConsentMain;
        }
        else
        {
          return GetConsentMainInterface(childControl.Parent);
        }
      }
    }

    /// <summary>
    /// Sets the web service URL and timeout.
    /// </summary>
    private void SetWebServiceUrlAndTimeout()
    {
      try
      {

        Dictionary<string, string> configDic = GetConfigDictionary(ConsentExecuteInfo["sysInstNm"]);

        this.PluginExecuteInfo.Add("consentSvcUrl", configDic["consentSvcUrl"]);
        this.PluginExecuteInfo.Add("hospitalSvcUrl", configDic["hospitalSvcUrl"]);
        this.PluginExecuteInfo.Add("formServiceUrl", configDic["formServiceUrl"]);
        this.PluginExecuteInfo.Add("imageUploadServerUrl", configDic["imageUploadServerUrl"]);
        this.PluginExecuteInfo.Add("signatureServerUrl", configDic["signatureServerUrl"]);
        this.PluginExecuteInfo.Add("signatureServerPort", configDic["signatureServerPort"]);
        this.PluginExecuteInfo.Add("imageUploadPath", configDic["imageUploadPath"]);
        this.PluginExecuteInfo.Add("ConsentSearchStartDate", configDic["ConsentSearchStartDate"]);
        this.PluginExecuteInfo.Add("timeOut", "10");

        this.consentWebService = WebMethodCommon.GetConsentWebService(configDic["consentSvcUrl"]);
        this.hospitalWebService = WebMethodCommon.GetHospitalWebService(configDic["hospitalSvcUrl"]);
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    public ConsentSvcRef.ConsentSvcSoapClient getConsentWebService()
    {
      return this.consentWebService;
    }

    public HospitalSvcRef.HospitalSvcSoapClient getHospitalWebService()
    {
      return this.hospitalWebService;
    }

    /// <summary>
    /// Initializes the parameters.
    /// </summary>
    public void initParams()
    {
      InitParamSetting(mCallParm);
    }

    /// <summary>
    /// 화면 초기화 시 수행해야 할 이벤트 처리
    /// </summary>
    /// <param name="e"></param>
    protected override void OnLoad(EventArgs e)
    {

      try
      {
        // 출력을 사용하면 프로그램 종료 이벤트 추가
        if (ConsentExecuteInfo["printAct"].Equals("Y"))
        {
          this.Parent.Disposed += Parent_Disposed;
        }

        if (string.IsNullOrEmpty(this.PluginModuleName))
        {
          return;
        }

        // 고정 모니터 설정
        MoniterViewSetting(ConsentExecuteInfo["printYN"].Equals("Y") ? true : false);

        if (ConsentExecuteInfo["printYN"].Equals("Y"))
        {
          this.Parent.Visible = false;
        }

        // 기존 인증서 삭제
        SignatureConfig sign = new SignatureConfig();
        if (!startform)
        {
          startform = false;
          sign.SignAllClear();
        }

        // eFormViewer 컨트롤 초기화
        InitEFormControl();

        HospitalSvcRef.SingleReturnData baseData = this.hospitalWebService.GetBaseData(ConsentExecuteInfo["dutinstcd"]);
        String[] strAr = baseData.responseData.Split(',');

        for (int i = 0; i < strAr.Length; i++)
        {
            String[] dataAr = strAr[i].Split('|');

            String key = "";
            String value = "";
            for (int j = 0; j < dataAr.Length; j++)
            {

                if (j == 0)
                {
                    key = dataAr[j];
                }
                else
                {
                    value = dataAr[j];
                }

            }
            SETTING_DATA.Add(key, value);

        }

                // TODO 201909
                // 경북대학교병원 특정 옵션 호출 시 조회 화면 제거 루틴 추가 필요
                //ConsentExecuteInfo["useListView"] = "N";
                //ConsentExecuteInfo["patientListView"] = "N";

                InvokeDelayedLoadEvent();

        this.eFormViewerCtrl.GetCurrentViewer().UIUpdateOnDrawing
            += new Viewer.UIUpdateOnDrawingHandler(ConsentMainControl_UIUpdateOnDrawing);

        base.OnLoad(e);

        // dbs227
        // TODO 디버그 용 메시지 박스
        //Boolean openDualView = (this.consentWebService.getDualViewMode(ConsentExecuteInfo["dutinstcd"],
        //            ConsentExecuteInfo["ipaddr"]) == "Y") ? true : false;
        //MessageBox.Show("Waiting for debugging at " + ConsentExecuteInfo["ipaddr"]);


        // Ku2.0 연동
        GetConsentListByFormcd();

        // 폰트 설치여부 체크
        string familyName;
        string familyList = "";
        FontFamily[] fontFamilies;

        System.Drawing.Text.InstalledFontCollection installedFontCollection = new System.Drawing.Text.InstalledFontCollection();

        fontFamilies = installedFontCollection.Families;

        int count = fontFamilies.Length;
        int fontCheck = 0;
        for (int j = 0; j < count; ++j)
        {
          familyName = fontFamilies[j].Name;
          familyList = familyList + familyName;
          familyList = familyList + ",  ";
          if (fontCheck != 1 && (familyName == "나눔고딕" || familyName == "NanumGothic"))
          {
            fontCheck = fontCheck + 1;
          }
          if (fontCheck < 100 && (familyName == "나눔고딕 ExtraBold" || familyName == "NanumGothicExtraBold" || familyName == "나눔고딕 아주 굵게"))
          {
            fontCheck = fontCheck + 10;
          }
        }

        // 폰트 설치 실행
        if (fontCheck < 11)
        {
          System.Diagnostics.Process UserProcess = new System.Diagnostics.Process();
          UserProcess.StartInfo.UseShellExecute = true;
          //UserProcess.StartInfo.FileName = "NanumFontSetup.exe";
          //UserProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(Application.StartupPath + "/Font/");
          // 폰트가 없어 최초 실행 시 에러 발생 부분 수정
          UserProcess.StartInfo.FileName = "FontInstall.exe";
          UserProcess.StartInfo.WorkingDirectory = Path.GetDirectoryName(Application.StartupPath + "\\");
          UserProcess.StartInfo.CreateNoWindow = true;
          UserProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
          UserProcess.Start();
        }

        string sTempPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Clipsoft\ClipSoft.eForm.Viewer\DataTemp\";

        if (Directory.Exists(sTempPath))
        {
          string[] filePaths = Directory.GetFiles(sTempPath);

          foreach (string fileName in filePaths)
          {
            FileInfo fileInfo = new FileInfo(fileName);
            if (fileInfo.Extension.Equals(".ept") || fileInfo.Extension.Equals(".jpg") || fileInfo.Extension.Equals(".xml"))
            {
              fileInfo.Delete();
            }
          }
        }

        if (multiParams != null && multiParams.Count > 0) {
          int pageCount = Int32.TryParse(((Dictionary<string, object>)multiParams[multiParams.Count - 1])["PAGE_COUNT"].ToString(), out int page) ? page : 0;

          showConsentView(pageCount);
          Boolean openDualView = (this.consentWebService.getDualViewMode(ConsentExecuteInfo["dutinstcd"], ConsentExecuteInfo["ipaddr"]) == "Y") ? true : false;
          if (openDualView)
          {
            consentCommandCtrl.RunConsentDualView();
          }
        }
      }
      catch (Exception ex)
      {
        // 데이터베이스 저장 기능 추가로 해당 기능 삭제
        //File.WriteAllText(string.Format(@"{0}\eConsentLog\{1}_Agent.txt", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
        //                                                          , DateTime.Now.ToString("yyyyMMdd_HHmmss"))
        //                , ex.ToString());
        Console.WriteLine(ex.ToString());

        if (this.Parent is System.Windows.Forms.Form)
        {
          ((Form)this.Parent).DialogResult = DialogResult.Cancel;
          ((Form)this.Parent).Close();
        }
      }
    }

    // 화면이 종료될때 Agent도 종료되도록 수정        
    /// <summary>
    /// Handles the Disposed event of the Parent control.
    /// </summary>
    /// <param name="sender">The source of the event.</param>
    /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    private void Parent_Disposed(object sender, EventArgs e)
    {
      foreach (Form form in Application.OpenForms)
      {
        if (form.Name.Equals("ConsentAgentForm"))
        {
          form.Dispose();
          break;
        }
      }
    }

    // 화면이 종료될때 Agent도 종료되도록 수정        
    /// <summary>
    /// Parents the disposed.
    /// </summary>
    public void Parent_Disposed()
    {
      foreach (Form form in Application.OpenForms)
      {
        if (form.Name.Equals("ConsentAgentForm"))
        {
          form.Dispose();
          break;
        }
      }
    }

    /// <summary>
    /// OCX 로 부터 넘겨 받은 파라미터를 decode
    /// </summary>
    /// <param name="pCallParm">EXEC_OPT 로 넘어온 파라미터 목록</param>
    /// <exception cref="Exception">CallParam 미전달</exception>
    private void InitParamSetting(object pCallParm)
    {

      try
      {
        if (pCallParm != null)
        {
          Dictionary<string, object> callParam = pCallParm as Dictionary<string, object>;
          if (callParam != null && callParam.Count < 2)
          {
            if (callParam["CALL_PARAMS"] != null)
            {
              pCallParm = callParam["CALL_PARAMS"] as object;
            }
          }

          foreach (KeyValuePair<string, object> callKV in pCallParm as Dictionary<string, object>)
          {

            // 사용자 정보
            if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "USER_INFO")
            {
              foreach (KeyValuePair<string, object> userKV in callKV.Value as Dictionary<string, object>)
              {
                if (userKV.Key != null && !string.IsNullOrEmpty(userKV.Key.ToString()) && userKV.Key.ToString() == "USER_ID")
                {
                  if (userKV.Value != null)
                  {
                    ConsentExecuteInfo["userNo"] = userKV.Value.ToString();
                    ConsentExecuteInfo["loginUserNo"] = userKV.Value.ToString();
                  }
                }
                else if (userKV.Key != null && !string.IsNullOrEmpty(userKV.Key.ToString()) && userKV.Key.ToString() == "DUTINSTCD")
                {
                  if (userKV.Value != null)
                  {
                    ConsentExecuteInfo["dutinstcd"] = userKV.Value.ToString();
                  }
                }
                else if (userKV.Key != null && !string.IsNullOrEmpty(userKV.Key.ToString()) && userKV.Key.ToString() == "USER_NAME")
                {
                  if (userKV.Value != null)
                  {
                    ConsentExecuteInfo["userName"] = userKV.Value.ToString();
                    ConsentExecuteInfo["loginUserName"] = userKV.Value.ToString();
                  }
                }
                else if (userKV.Key != null && !string.IsNullOrEmpty(userKV.Key.ToString()) && userKV.Key.ToString() == "USER_DEPTCD")
                {
                  if (userKV.Value != null)
                  {
                    ConsentExecuteInfo["userDeptCd"] = userKV.Value.ToString();
                  }
                }
                else if (userKV.Key != null && !string.IsNullOrEmpty(userKV.Key.ToString()) && userKV.Key.ToString() == "USER_DEPTNM")
                {
                  if (userKV.Value != null)
                  {
                    ConsentExecuteInfo["userDeptName"] = userKV.Value.ToString();
                  }
                }
              }
            }

            // 환자 정보
            if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "PATIENT_INFO")
            {
              foreach (KeyValuePair<string, object> patientKV in callKV.Value as Dictionary<string, object>)
              {
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "PTNT_NO")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["patientNo"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "VISIT_TYPE")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["visitType"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CLN_DEPT")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["clnDept"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CLN_DATE")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["clnDate"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CRETNO")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["cretno"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CLN_DX_NM")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["clnDxNm"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "OPRSRVNO")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["opRsrvNo"] = patientKV.Value.ToString();
                }
              }
            }

            if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "EXEC_OPT")
            {
              // 화면 설정 정보
              foreach (KeyValuePair<string, object> execKV in callKV.Value as Dictionary<string, object>)
              {
                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "USE_LIST_VIEW")
                {
                  if (execKV.Value != null) ConsentExecuteInfo["useListView"] = execKV.Value.ToString(); // 동의서 리스트 사용 유무
                }
                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "PTNT_LIST_VIEW")
                {
                  if (execKV.Value != null) ConsentExecuteInfo["patientListView"] = execKV.Value.ToString(); // 환자 리스트 사용 유무
                }
                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "START_FORM_CD")
                {
                  if (execKV.Value != null) ConsentExecuteInfo["startFormCd"] = execKV.Value.ToString(); // 시작 FORM ID
                }
                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "PTNT_ACT")
                {
                  if (execKV.Value != null) ConsentExecuteInfo["printAct"] = execKV.Value.ToString(); // 초기 프린트
                }
                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "PRINT_LIST")
                {
                  if (execKV.Value != null)
                  {
                    if (execKV.Value is List<object> PatientList && PatientList.Count > 0)
                    {

                      PrintInfoList = new List<ConsentFormListVO>();

                      ConsentFormListVO consentVO = new ConsentFormListVO();

                      for (int i = 0; i < PatientList.Count; i++)
                      {

                        consentVO = new ConsentFormListVO {
                          printCnt = -1
                        };

                        foreach (KeyValuePair<string, object> callOrderKV in PatientList[i] as Dictionary<string, object>)
                        {
                          if (callOrderKV.Key != null && !string.IsNullOrEmpty(callOrderKV.Key.ToString()) && callOrderKV.Value != null)
                          {
                            if (callOrderKV.Key.ToString() == "START_FORM_CD") consentVO.formCd = callOrderKV.Value.ToString(); // 출력 서식코드
                            if (callOrderKV.Key.ToString() == "PTNT_NO") consentVO.pid = callOrderKV.Value.ToString(); // 환자번호
                            if (callOrderKV.Key.ToString() == "VISIT_TYPE") consentVO.ordType= callOrderKV.Value.ToString(); // 내원구분
                            if (callOrderKV.Key.ToString() == "CLN_DATE") consentVO.inDd = callOrderKV.Value.ToString(); // 진료일자
                            if (callOrderKV.Key.ToString() == "CLN_DEPT") consentVO.ordDeptCd = callOrderKV.Value.ToString(); // 진료과
                            if (callOrderKV.Key.ToString() == "PRINT_CNT")
                            {

                              int.TryParse(callOrderKV.Value.ToString(), out int PrntCnt);
                              consentVO.printCnt = PrntCnt; // 출력 카운트
                            }
                            if (callOrderKV.Key.ToString() == "CRETNO")
                            {
                              int.TryParse(callOrderKV.Value.ToString(), out int cretno);
                              consentVO.cretNo = cretno; // 차트번호
                            }
                          }
                        }
                        PrintInfoList.Add(consentVO);
                      }
                      if (execKV.Value != null) ConsentExecuteInfo["printList"] = PrintInfoList.Count.ToString(); // 출력 데이터
                    }
                  }
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "FORMCD")
                { // 서식 코드
                  if (execKV.Value != null) ConsentExecuteInfo["formCd"] = execKV.Value.ToString();
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "OCRTAG")
                { // OCR 태그
                  if (execKV.Value != null) ConsentExecuteInfo["ocrTag"] = execKV.Value.ToString();
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "TEMP_SAVE")
                { // 임시 저장 (Ku2.0 연동)
                  if (execKV.Value != null) ConsentExecuteInfo["tempSave"] = execKV.Value.ToString();
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "PRINT_YN")
                { // 출력 여부 (Ku2.0 연동)
                  if (execKV.Value != null) ConsentExecuteInfo["printYN"] = execKV.Value.ToString();
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "PRINT_CNT")
                { // 출력 매수 (Ku2.0 연동)
                  if (execKV.Value != null) ConsentExecuteInfo["printCount"] = execKV.Value.ToString();
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "SYSINSTNM")
                { // 접속 서버 정보
                  if (execKV.Value != null)
                  {

                    string instCd = string.Empty;

                    instCd = execKV.Value.ToString().Contains("본원") ? "031" : execKV.Value.ToString().Contains("칠곡") ? "032" : string.Empty;
                    instCd += execKV.Value.ToString().Contains("교육") ? "edu" : string.Empty;
                    //instCd = "Dev";

                    ConsentExecuteInfo["sysInstNm"] = instCd;
                  }
                }

                if (execKV.Key != null && !string.IsNullOrEmpty(execKV.Key.ToString()) && execKV.Key.ToString() == "READONLY")
                { // 보기 전용 여부
                  if (execKV.Value != null) ConsentExecuteInfo["readOnly"] = execKV.Value.ToString();
                }
              }
            }

            // 원무
            if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "PAM_INFO")
            {
              foreach (KeyValuePair<string, object> patientKV in callKV.Value as Dictionary<string, object>)
              {
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "SPEC_DR_YN")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["SpecDoctorYN"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_START_DT")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContStartDate"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_END_DT")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContEndDate"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "ROOM_CAPA")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["RoomCapa"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_TELNO")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContTelNo"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_STAFF1")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContStaff1Name"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_STAFF2")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContStaff2Name"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CONT_STAFF3")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["ContStaff3Name"] = patientKV.Value.ToString();
                }
                if (patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "CARD_NO")
                {
                  if (patientKV.Value != null) ConsentExecuteInfo["CardNo"] = patientKV.Value.ToString();
                }
                // 경대병원 원무 태그 추가
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG1") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag1"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG2") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag2"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG3") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag3"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG4") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag4"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG5") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag5"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG6") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag6"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG7") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag7"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG8") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag8"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG9") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag9"] = patientKV.Value.ToString();
                }
                if(patientKV.Key != null && !string.IsNullOrEmpty(patientKV.Key.ToString()) && patientKV.Key.ToString() == "TAG10") {
                  if(patientKV.Value != null)
                    ConsentExecuteInfo["tag10"] = patientKV.Value.ToString();
                }
              }
            }
          }
        }
        else
        {
          throw new Exception("CallParam 미전달");
        }

        // IP 주소 확인
        string printIp = string.Empty;
        foreach (System.Net.IPAddress ip in System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName()))
        {
          if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
          {
            printIp = ip.ToString();
            break;
          }
        }

        // dbs227, 경북대학교병원 ip address 기록
        ConsentExecuteInfo["ipaddr"] = printIp;

        if (!printIp.Equals(string.Empty))
        {
          string[] ipArr = printIp.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
          if (ipArr.Length == 4)
          {
            printIp = string.Format("{0}.{1}", ipArr[2], ipArr[3]);
          }
          else
          {
            printIp = string.Empty;
          }
        }

        ConsentExecuteInfo["printIP"] = printIp;

        //버전정보
        string[] versionName = Assembly.GetExecutingAssembly().FullName.Split(',')[1].Split('.');
        string version = versionName[versionName.Length - 1];
        ConsentExecuteInfo["DeviceType"] = "WIN," + version + "," + ConsentExecuteInfo["dutinstcd"];
      }
      catch (Exception ex)
      {
        throw ex;
      }
    }

    /// <summary>
    /// 모니터 뷰 설정
    /// </summary>
    /// <param name="printMode">출력 여부</param>
    private void MoniterViewSetting(bool printMode)
    {
      // 출력 모드라면 화면에 나타내지 않는다
      if (printMode)
      {
        return;
      }

      //현재 프로그램이 실행되고 있는정보 가져오기: 디버깅 모드라면 bin/debug/프로그램명.exe
      FileInfo exefileinfo = new FileInfo(Path.GetDirectoryName(Application.StartupPath));

      // AppDomain.CurrentDomain.DynamicDirectory
      // Server.MapPath("~")
      string path = Path.GetDirectoryName(Application.StartupPath);//
      string fileName = @"\config.ini";  //파일명

      //만약 현재 실행 되는 경로가 아닌 특정한 위치를 원한다면 위에 과정 상관없이 바로 경로셋팅 해 주면 된다. (예: c:\config.ini) 
      string filePath = path + fileName;   //ini 파일 경로 

      iniUtil ini = new iniUtil(filePath);   // 만들어 놓았던 iniUtil 객체 생성(생성자 인자로 파일경로 정보 넘겨줌)

      //이제 ini 객체를 이용해 맘것 사용하면 된다.
      string sMoniterNumber = ini.GetIniValue("DFH", "MONITER_NUMBER");
      int iMoniterNumber = 0;
      int.TryParse(sMoniterNumber, out iMoniterNumber);

      Point location = Point.Empty;
      int j = 1;
      FormWindowState windowStateBackup;
      foreach (Screen sc in Screen.AllScreens)
      {
        // 출력할 모니터에 Form 을 생성하여 나타낸다
        if (j == iMoniterNumber)
        {
          Form parentForm = this.Parent as Form;

          if (parentForm != null)
          {
            windowStateBackup = parentForm.WindowState;
            Size size = parentForm.Bounds.Size;
            parentForm.WindowState = FormWindowState.Normal;
            parentForm.StartPosition = FormStartPosition.Manual;
            parentForm.ClientSize = new Size(size.Width, size.Height);
            parentForm.Location = new Point(sc.Bounds.Left, sc.Bounds.Top);
            parentForm.WindowState = windowStateBackup;
          }
          break;
        }
        j++;
      }
    }

    /// <summary>
    /// eFormViewer 컨트롤에 대한 초기화
    /// run option 설정
    /// </summary>
    private void InitEFormControl()
    {
      Screen screen = Screen.FromControl(this);
      var zoomRate = "100";       // 기본값
      var tempValue = hospitalWebService.getZoomRate(ConsentExecuteInfo["dutinstcd"]);

      if (!string.IsNullOrEmpty(tempValue))
      {
        zoomRate = tempValue;
      }
      if (screen.Primary)
      {
        //this.eFormViewerCtrl.SetRunOption("DEFAULT_ZOOM_RATE", "pagewidth");
        this.eFormViewerCtrl.SetRunOption("DEFAULT_ZOOM_RATE", zoomRate);
      }
      else
      {
        this.eFormViewerCtrl.SetRunOption("DEFAULT_ZOOM_RATE", "pagewidth");
      }
      string apiResult = string.Empty;
      string[] penOtps = null;
      //string alpathHexValue = "127";  // 기본 투명도
      string widthValue = "9";    // 기본 굵기
      System.Drawing.Color color = Color.FromArgb(127, 255, 255, 1);  // 기본색

      if (hospitalWebService != null)
      {
        apiResult = hospitalWebService.getPenOptions(ConsentExecuteInfo["dutinstcd"]);
        if (apiResult.Length > 0)
        {
          penOtps = apiResult.Split(',');
          int alpha = Convert.ToInt32(penOtps[1]);
          int MULTI_CONST = 254;
          int MULTI_PEPRC = 100;

          string hexValue = penOtps[0].Replace("#", "");

          color = Color.FromArgb(Convert.ToInt32(penOtps[1]),
              Convert.ToInt32(hexValue.Substring(0, 2), 16),
              Convert.ToInt32(hexValue.Substring(2, 2), 16),
              Convert.ToInt32(hexValue.Substring(4, 2), 16));
          //color = System.Drawing.ColorTranslator.FromHtml(penOtps[0]);
          widthValue = penOtps[2];
        }
      }


      //this.eFormViewerCtrl.SetRunOption("ENABLE_DEBUG_VIEW", "true");
      //this.eFormViewerCtrl.SetRunOption("DEFAULT_TOOL_BAR_VISIBLE", "true");
      this.eFormViewerCtrl.SetRunOption("USE_CREDITCARD_SIGNPAD", "false");
      this.eFormViewerCtrl.SetRunOption("DEFAULT_TOOL_BAR_VISIBLE", "false");
      this.eFormViewerCtrl.SetRunOption("SET_EXTERNAL_CONTROL_DEFINED_PATH", this.PluginExecuteInfo["formServiceUrl"]);
      this.eFormViewerCtrl.SetRunOption("USE_EITHER_SIDE_MOVE_BUTTON", "true");
      this.eFormViewerCtrl.SetRunOption("DUALVIEWER_TOOL_BAR_SIZE", "32");
      var penStrValue = "{ \"width\":\"" + widthValue
          + "\",\"color\":{ \"a\":\""
              + color.A.ToString() + "\", \"r\":\""
              + color.R.ToString() + "\", \"g\":\""
              + color.G.ToString() + "\", \"b\":\""
              + color.B.ToString() + "\"} }";
      // dbs227, 경북대학교병원 옵션, 형광펜 색으로
      this.eFormViewerCtrl.SetRunOption("DRAWING_PEN", "{ \"width\":\"" + widthValue
          + "\",\"color\":{ \"a\":\""
              + color.A.ToString() + "\", \"r\":\""
              + color.R.ToString() + "\", \"g\":\""
              + color.G.ToString() + "\", \"b\":\""
              + color.B.ToString() + "\"} }");
      this.eFormViewerCtrl.SetRunOption("SET_VISIBLE_BUTTONS", "PAGE_ATTACH=true");
      this.eFormViewerCtrl.SetRunOption("IMAGE_SAVE_OPTION", "{\"dpi\":\"150\",\"gray\":\"false\",\"encode\":\"jpeg\",\"base-index\":\"1\",\"quality\":\"100\"}");
      // dbs227, 경북대학교병원 요청사항
      // 마우스 우클릭 그리기 모드 변경
      this.eFormViewerCtrl.SetRunOption("SET_MOUSE_RIGHT_CHANGE_MODE", "Drawing");
	  // true 로 설정 시 TabPoint 프로그램을 통한 듀얼 모니터 제어
	  // false 로 설정 시 윈도우 드라이버로 듀얼 보니터 제어
      //this.eFormViewerCtrl.SetRunOption("USE_DUALVIEWER_ACU", "true");

      if (HasVerticalMonitor)
      {
        this.eFormViewerCtrl.SetRunOption("RUN_AS_DUALVIEWER", "CLIP.eForm.DualViewer.dll");
        //                this.eFormViewerCtrl.SetRunOption("READ_ONLY", "true");
        this.eFormViewerCtrl.SetRunOption("DUALVIEWER_TO_ACTIVATE_CONTROLS", "true");
        this.eFormViewerCtrl.SetRunOption("SET_VISIBLE_DUALVIEWER_TOOLSTRIP_MENU", "false");
        this.eFormViewerCtrl.SetRunOption("DUALVIEWER_TOOL_BAR_ENABLE", "true");

        // 툴바 위치 조절(true : 상단, false : 하단)
        this.eFormViewerCtrl.SetRunOption("USE_DUALVIEWER_TOOL_BAR_TOP", "false");

        // 가상키보드 사용 여부
        this.eFormViewerCtrl.SetRunOption("DUALVIEWER_VIRTUAL_KEYBOARD_VISIBLE", "true");

        // 관리자 권한 실행 저장 여부
        this.eFormViewerCtrl.SetRunOption("USE_ADMIN_PRIVILEGES_SAVE_EXECUTE", "false");

        this.eFormViewerCtrl.SetRunOption("DUALVIEWER_RESOLUTION", "{\"width\":\"768\",\"height\":\"1024\"}");
      }
    }

    /// <summary>
    /// Invokes the delayed load event.
    /// </summary>
    private void InvokeDelayedLoadEvent() // TODO: 리팩터링 대상 comment by jchong 2016.06.11
    {
      if (this.OnLoadPartControls != null)
      {
        Application.DoEvents();
        Thread.Sleep(1);

        OnLoadPartControls.Invoke(this, new EventArgs());
      }
    }

    /// <summary>
    /// </summary>
    /// <param name="msg">A <see cref="T:System.Windows.Forms.Message" />, passed by reference, that represents the window message to process.</param>
    /// <param name="keyData">One of the <see cref="T:System.Windows.Forms.Keys" /> values that represents the key to process.</param>
    /// <returns>
    /// true if the character was processed by the control; otherwise, false.
    /// </returns>
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
      if (msg.Msg == 0x100)
      {
        if (keyData == Keys.PageUp)
        {
          this.eFormViewerCtrl.MovePrevPage();
        }

        if (keyData == Keys.Next)
        {
          this.eFormViewerCtrl.MoveNextPage();
        }
      }
      return base.ProcessCmdKey(ref msg, keyData);
    }

    /// <summary>
    /// Consents the main control UI update on drawing.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="undoStackCount">The undo stack count.</param>
    /// <param name="redoStackCount">The redo stack count.</param>
    /// <param name="totalStrokeCount">The total stroke count.</param>
    /// <param name="totalAllPageStrokeCoun">The total all page stroke coun.</param>
    void ConsentMainControl_UIUpdateOnDrawing(object sender, int undoStackCount, int redoStackCount, int totalStrokeCount, int totalAllPageStrokeCoun)
    {
      if (undoStackCount > 0)
      {
        this.consentCommandCtrl.EnableUndo = true;
      }
      else
      {
        this.consentCommandCtrl.EnableUndo = false;
      }

      if (redoStackCount > 0)
      {
        this.consentCommandCtrl.EnableRedo = true;
      }
      else
      {
        this.consentCommandCtrl.EnableRedo = false;
      }

      if (totalStrokeCount > 0)
      {
        this.consentCommandCtrl.EnableRemoveAll = true;
      }
      else
      {
        this.consentCommandCtrl.EnableRemoveAll = false;
      }
    }

    ConsentListCtrlBase IConsentMain.ConsentListCtrl
    {
      get { return this.consentListCtrl; }
    }

    PatientInfoCtrlBase IConsentMain.PatientInfoCtrl
    {
      get { return this.patientInfoCtrl; }
    }

    PatientListCtrlBase IConsentMain.PatientListCtrl
    {
      get { return this.patientListCtrl; }
    }

    Dictionary<string, string> IConsentMain.ConsentExecuteInfo
    {
      get
      {
        return this.ConsentExecuteInfo;
      }
      set
      {
        this.ConsentExecuteInfo = value;
      }
    }

    Dictionary<string, string> IConsentMain.PluginExecuteInfo
    {
      get
      {
        return this.PluginExecuteInfo;
      }
      set
      {
        this.PluginExecuteInfo = value;
      }
    }

    ConsentCommandCtrlBase IConsentMain.ConsentCommandCtrl
    {
      get
      {
        return this.consentCommandCtrl;
      }
    }

    void IConsentMain.changeInDd(string inDd)
    {
      consentListCtrl.changeInDd(inDd);
    }

    public Dictionary<string, object> ProcessResultValue
    {
      get
      {
        return processResultValues;
      }
    }

    /// <summary>
    /// 환자 정보가 바뀌었을때 컨트롤들의 정보를 재조회        
    /// </summary>
    /// <param name="visitType">Type of the visit.</param>
    void IConsentMain.UIControlsRefeash(string visitType)
    {
      this.patientInfoCtrl.OnRefeashPartControls(visitType);
      this.consentListCtrl.OnRefeashPartControls();
    }


    /// <summary>
    /// 사용자 정보 변경
    /// </summary>
    /// <param name="pInstCd">근무지기관코드</param>
    /// <param name="pUserId">사용자ID</param>
    /// <param name="DutPlceCd">근무지부서</param>
    void IConsentMain.SetConsentUserInfo(string pInstCd, string pUserId, string DutPlceCd)
    {
      this.patientInfoCtrl.SetConsentUserInfo(pUserId, pInstCd, DutPlceCd);
    }

    void IConsentMain.SetConsentUserInfo(string pInstCd, string pUserId, string DutPlceCd, string temp) {
      this.patientInfoCtrl.SetConsentUserInfo(pUserId, pInstCd, DutPlceCd);
    }

    void IConsentMain.ClearPreviewConsent(bool pDoInit)
    {
      consentCommandCtrl.CurrentPreviewConsent = null;
      patientInfoCtrl.SetConsentDocumentName("");

      if (pDoInit)
      {
        eFormViewerCtrl.Visible = false;
        eFormViewerCtrl.CloseDualViewer();
        //eFormViewerCtrl.ReInitializeViewer();
        imageViewCtrl1.Hide();
      }
    }

    void IConsentMain.PreviewConsent(string fos)
    {
      this.pnlCommand.Visible = true;
      this.pnlViewer.Visible = false;
      this.eFormViewerCtrl.Visible = true;
      this.eFormViewerCtrl.OpenFos(fos);
    }

    void IConsentMain.ClearConsent()
    {
      this.pnlCommand.Visible = true;
      this.pnlViewer.Visible = false;
      this.eFormViewerCtrl.Visible = true;
      this.eFormViewerCtrl.Open();
    }

    void IConsentMain.ReviewConsent()
    {
      this.pnlCommand.Visible = false;
      this.pnlViewer.Visible = true;
      this.eFormViewerCtrl.Visible = false;
      eFormViewerCtrl.CloseDualViewer();
    }

    void IConsentMain.RunConsentDualView()
    {
      this.eFormViewerCtrl.OpenDualViewer();
    }

    /// <summary>
    /// Prints the consent document.
    /// 수동으로 찾아서출력
    /// 일반 출력의 경우에도 기본프린터로 바로 출력하는 것으로 변경됨
    /// </summary>
    /// <param name="fos">The fos.</param>
    void IConsentMain.PrintConsentDocument(string fos)
    {
      //int rid = -1;
      if (!string.IsNullOrEmpty(fos))
      {
        this.eFormViewerCtrl.OpenFos(fos);
        // dbs227 DB 기록 필요
        //rid = this.consentCommandCtrl.SaveDataForPrintedConsent(String.Empty);
      }
      this.printSaveStatus = false;

      int iPrntCnt = 0;

      //PC 클라이언트에서 출력 버튼 눌럿을때를 구분하여 pageCount넘겨줌 
      //pageCount를 넘겨주지 않고 consentCommandCtrl.CurrentPreviewConsent.PrntCnt에서 출력 장수를 받았을때 초기화되어 익셉션 발생
      if (printButtonClick)
      {
        iPrntCnt = pageCnt;
        printButtonClick = false;
      }
      else
      {
        iPrntCnt = consentCommandCtrl.CurrentPreviewConsent.prntCnt;
      }

      this.multiPrintPlanCnt = iPrntCnt;
      this.multiPrintExecCnt = 0;
      this.checkAutoPrint = false; //수동출력

      if (iPrntCnt > 0)
      {
        // 출력매수만큼 동의서 출력
        //for (int i = 0; i < iPrntCnt; i++)
        //{
        //    if((i+1) == iPrntCnt) this.printSaveStatus = true;
        this.printSaveStatus = true;
        this.eFormViewerCtrl.PrintByPrinterName("");
        //}
      }
      this.printSaveStatus = false;

      // dbs227, 
      // 출력 모드가 아닐때는 초기화 하지 않는다.
      //if (rid > 0)
      //{
      //    this.consentListCtrl.InquiryConsentData(rid);
      //}
    }

    /// <summary>
    /// 기본프린터로 출력, Agent에서 직접출력
    /// dbs227, 경북대학교병원 사용하지 않음
    /// </summary>
    /// <param name="fos">출력할 FOS string</param>
    void IConsentMain.PrintDirect(string fos)
    {
      if (!string.IsNullOrEmpty(fos))
      {
        // dbs227 DB 기록 필요
        //this.consentCommandCtrl.SaveDataForPrintedConsent(String.Empty);

        this.eFormViewerCtrl.OpenFos(fos);
        //this.consentCommandCtrl.SaveDataForPrintedConsent(String.Empty);
      }

      int prntCnt = 0;
      prntCnt = consentCommandCtrl.CurrentPreviewConsent.prntCnt;
      this.checkAutoPrint = true;//자동출력

      if (!string.IsNullOrEmpty(this.ConsentExecuteInfo["printList"]))
      {
        if (!ConsentExecuteInfo["prntCnt"].Equals("-1"))
        {
          int.TryParse(this.ConsentExecuteInfo["prntCnt"].ToString(), out prntCnt);
        }
      }

      this.multiPrintPlanCnt = prntCnt;
      this.multiPrintExecCnt = 0;

      if (prntCnt > 0)
      {
        //this.printSaveStatus = false;
        //// 출력매수만큼 동의서 출력
        //for (int i = 0; i < prntCnt; i++)
        //{
        //    if ((i + 1) == prntCnt) this.printSaveStatus = true;
        this.printSaveStatus = true;
        //기본프린터로 바로 출력하기로 함
        this.eFormViewerCtrl.PrintByPrinterName("");
        //}
        //this.printSaveStatus = false;
      }
    }

    void IConsentMain.MoveFirstPage()
    {
      this.eFormViewerCtrl.MoveFirstPage();
    }

    void IConsentMain.MovePrevPage()
    {
      this.eFormViewerCtrl.MovePrevPage();
    }

    void IConsentMain.MoveNextPage()
    {
      this.eFormViewerCtrl.MoveNextPage();
    }

    void IConsentMain.MoveLastPage()
    {
      this.eFormViewerCtrl.MoveLastPage();
    }

    void IConsentMain.Save()
    {
      this.eFormViewerCtrl.Save();
    }

    /// <summary>
    /// eFormViewerCtrl 컨트롤의 TempSave 이벤트를 호출
    /// </summary>
    void IConsentMain.TempSave()
    {
      this.eFormViewerCtrl.TempSave();
    }

    int IConsentMain.GetCurrentPageIndex()
    {
      return this.eFormViewerCtrl.GetCurrentPageIndex();
    }

    int IConsentMain.GetTotalPageCount()
    {
      return this.eFormViewerCtrl.GetTotalPageCount();
    }

    void IConsentMain.MoveToPageIndex(int pageIndex)
    {
      this.eFormViewerCtrl.MoveToPageIndex(pageIndex);
    }

    void IConsentMain.SetZoomRate(string zoomRate)
    {
      this.eFormViewerCtrl.SetZoomRate(zoomRate);
    }

    void IConsentMain.EnableDrawing(bool enable)
    {
      this.eFormViewerCtrl.EnableDrawing(enable);
    }

    bool IConsentMain.IsDrawMode()
    {
      return this.eFormViewerCtrl.IsDrawMode();
    }

    void IConsentMain.RemoveAllDrawing()
    {
      this.eFormViewerCtrl.RemoveAllDrawing();
    }

    void IConsentMain.UndoDrawing()
    {
      this.eFormViewerCtrl.UndoDrawing();
    }

    void IConsentMain.RedoDrawing()
    {
      this.eFormViewerCtrl.RedoDrawing();
    }

    void IConsentMain.ConfigDrawingPen()
    {
      this.eFormViewerCtrl.ConfigDrawingPen();
    }

    void IConsentMain.SetFingerScanValue(string controlId, string base64Image)
    {
      this.eFormViewerCtrl.SetFingerPrintImage(controlId, base64Image, true);
    }

    void IConsentMain.SetSignatureImage(string controlId, string base64Image)
    {
      this.eFormViewerCtrl.SetSignatureImage(controlId, base64Image, true);
    }

    public CLIP.eForm.ImageView.ImageViewCtrl GetImageViewerCtrl()
    {
      return this.imageViewCtrl1;
    }

    void IConsentMain.CloseSignaturePopup(string controlId)
    {
      this.eFormViewerCtrl.CloseSignaturePopup(controlId);
    }

    void IConsentMain.SetRunOption(string optionKey, string optionValue)
    {
      this.eFormViewerCtrl.SetRunOption(optionKey, optionValue);
    }

    void IConsentMain.TerminateConsentMain()
    {
      if (this.Parent is System.Windows.Forms.Form)
      {
        ((Form)this.Parent).DialogResult = DialogResult.Cancel;
        ((Form)this.Parent).Close();
      }
    }

    /// <summary>
    /// 첨지 삭제
    /// </summary>
    void IConsentMain.DeleteAttach()
    {
      this.eFormViewerCtrl.DeleteAttach();
    }

    /// <summary>
    /// 첨지 추가
    /// </summary>
    void IConsentMain.InsertAttach()
    {
      this.eFormViewerCtrl.InsertAttach();
    }

    /// <summary>
    /// 환자정보 설정
    /// </summary>
    void IConsentMain.SetPatientInfo()
    {
      this.patientInfoCtrl.SetPatientInfo();
    }

    /// <summary>
    /// Closes the dual viewer.
    /// </summary>
    public void CloseDualViewer()
    {
      this.eFormViewerCtrl.CloseDualViewer();
      this.consentCommandCtrl.SetEnableConsentIssueCommands(true);
      this.consentCommandCtrl.SetEnableButtonsByCurrentConsent();
    }

    /// <summary>
    /// 서명 시 이미지 파일 생성 된 후 호출
    /// </summary>
    /// <param name="value">저장 이미지 파일 설명</param>
    private void OnWrittenImageFile(string value)
    {
      this.consentCommandCtrl.WorkExtraWithSavedImageFiles(value);
    }

    /// <summary>
    /// Called when [written data XML file].
    /// </summary>
    /// <param name="value">The value.</param>
    private void OnWrittenDataXmlFile(string value)
    {

      string dataXmlValue = string.Empty;

      if (!string.IsNullOrEmpty(value))
      {

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(value);
        dataXmlValue = xmlDocument.InnerXml;

        outputDataDic = new Dictionary<string, string>();
        XmlNode rootNode = xmlDocument.SelectSingleNode("form-data");

        foreach (XmlNode childNode in rootNode.ChildNodes)
        {
          string fieldName = string.Empty;
          string fieldValue = string.Empty;

          XmlElement outFieldElement = childNode as XmlElement;

          if (outFieldElement != null)
          {
            fieldName = outFieldElement.Name;
            if (outFieldElement.ChildNodes.Count > 0
                && outFieldElement.ChildNodes[0] is XmlCDataSection)
            {
              fieldValue = ((XmlCDataSection)outFieldElement.ChildNodes[0]).InnerText;
            }

            if (outputDataDic.ContainsKey(fieldName))
            {
              outputDataDic[fieldName] = fieldValue;
            }
            else
            {
              outputDataDic.Add(fieldName, fieldValue);
            }
          }
        }

        if (processResultValues.ContainsKey("OUTPUT_VALUES"))
        {
          processResultValues["OUTPUT_VALUES"] = outputDataDic;
        }
        else
        {
          processResultValues.Add("OUTPUT_VALUES", outputDataDic);
        }
      }

      try
      {

        SingleReturnData returnData = this.consentWebService.CheckConsentState(int.Parse(consentCommandCtrl.CurrentPreviewConsent.consentMstRid), consentCommandCtrl.CurrentPreviewConsent.consentState);
        //int state = this.consentWebService.CheckConsentState(int.Parse(consentCommandCtrl.CurrentPreviewConsent.ConsentMstRid), consentCommandCtrl.CurrentPreviewConsent.ConsentState);
        int state = Int32.Parse(returnData.responseData);
        if (state == 1)
        {
          MessageBoxDlg.Show(this, "이미 저장된 서식 입니다."
                          , string.Format(Properties.Resources.msg_caption_confirm),
                          MessageBoxButtons.OK, MessageBoxIcon.Information);
          return;
        }

        string eptXmlValue = this.eFormViewerCtrl.GetTempSaveForm();

        bool isSaved = this.consentCommandCtrl.SaveCompleteConsentData(eptXmlValue, dataXmlValue, out object saveResult);

        if (processResultValues.ContainsKey("OTHER_VALUE_1"))
        {
          processResultValues["OTHER_VALUE_1"] = saveResult;
        }
        else
        {
          processResultValues.Add("OTHER_VALUE_1", saveResult);
        }

        if (isSaved)
        {
          if (ProcessResult != null)
          {
            ProcessResult.Invoke("SUCCESS");
          }
        }
        else
        {
          ProcessResult.Invoke("FAIL");
        }
      }
      catch (Exception ex)
      {
        System.Diagnostics.Trace.WriteLine(string.Format("CLIP.eForm error: {0}", ex.Message));

        MessageBoxDlg.Show(true, string.Format(ex.Message)
            , string.Format(Properties.Resources.msg_caption_fail),
            MessageBoxButtons.OK, MessageBoxIcon.Error);

        initConsent();

        ProcessResult.Invoke("FAIL");

      }
      finally
      {
        if (multiParams == null)
        {
          this.eFormViewerCtrl.CloseDualViewer();
        }
      }
    }

    private void OnWrittenTempSaveFile(string value)
    {
      XmlDocument xmlDocument = new XmlDocument();
      xmlDocument.Load(value);
      string eptXmlValue = xmlDocument.InnerXml;

      try
      {
        string dataXml = this.eFormViewerCtrl.GetDataXml();

        consentCommandCtrl.SaveTempConsentData(eptXmlValue, dataXml);

      }
      catch (Exception ex)
      {
        System.Diagnostics.Trace.WriteLine(string.Format("CLIP.eForm error: {0}", ex.Message));
        MessageBoxDlg.Show(true, string.Format(ex.Message)
            , string.Format(Properties.Resources.msg_caption_fail),
            MessageBoxButtons.OK, MessageBoxIcon.Error);
        initConsent();
        return;
      }
      finally
      {
        if (multiParams == null)
        {
          this.eFormViewerCtrl.CloseDualViewer();
        }
      }
    }

    public void SetConsentListSplitPanelVisibility(bool visibility)
    {
      if (!visibility)
      {
        this.splitConsent.Panel1Collapsed = true;
      }
    }

    public void SetPatientListSplitPanelVisibility(bool visibility)
    {
      if (!visibility)
      {
        this.splitPatient.Panel2Collapsed = true;
      }
    }

    public bool UseFingerScan { get; set; }
    public bool viewStatus { get; set; }

    public bool IsComplete()
    {
      bool _isComplete = false;

      if (consentCommandCtrl != null && consentCommandCtrl.CurrentPreviewConsent != null)
      {
        string _state = consentCommandCtrl.CurrentPreviewConsent.consentState ?? string.Empty;
        if (_state.Equals("ELECTR_CMP"))
        {
          _isComplete = true;
        }
      }

      return _isComplete;
    }

    private void panelReview_Resize(object sender, EventArgs e)
    {
      if (this.pnlViewer.Visible)
      {
        if (OnResizeReviewConsent != null)
        {
          OnResizeReviewConsent.Invoke(this, new EventArgs());
        }
      }
    }

    /// <summary>
    /// 동의서 뷰어 컨트롤 OnError 이벤트 핸들러
    /// </summary>
    /// <param name="errorCode">에러코드</param>
    /// <param name="errorMessage">에러 메시지</param>
    private void eFormViewerCtrl_OnError(string errorCode, string errorMessage)
    {

    }

    /// <summary>
    /// 동의서 뷰어 컨트롤 OnProcess 이벤트 핸들러
    /// </summary>
    /// <param name="eventCode">이벤트 코드</param>
    /// <param name="value">이벤트 값</param>
    private void eFormViewerCtrl_OnProcess(string eventCode, string value)
    {
      System.Diagnostics.Trace.WriteLine(string.Format("eventCode: {0} - value: {1}", eventCode, value));

      // 동의서의 현제 페이지 번호 설정
      if (eventCode.Equals("PAGING"))
      {
        this.consentCommandCtrl.OnPaging(this.eFormViewerCtrl.GetCurrentPageIndex());
      }

      // 듀얼 뷰어 버튼 활성화 여부 제어?
      if (eventCode.Equals("DUAL_VIEWER"))
      {
        if (value.Equals("OPEN"))
        {
          
          this.consentListCtrl.Enabled = false;
          this.patientInfoCtrl.Enabled = false;
          this.patientListCtrl.Enabled = false;
          //                    this.eFormViewerCtrl.SetRunOption("READ_ONLY", "false");
          this.consentCommandCtrl.EnablePenDrawing = true;
          this.consentCommandCtrl.EnablePenConfig = true;
          if (multiParams != null)
          {
            consentCommandCtrl.setMultiParamsDualViewrStripButton();
          }
          else
          {
            this.consentCommandCtrl.SetEnablementExecuteWhenDualViewerActive(false);
          }
        }

        if (value.Equals("CLOSE"))
        {
          this.consentListCtrl.Enabled = true;
          this.patientInfoCtrl.Enabled = true;
          this.patientListCtrl.Enabled = true;
          //                    this.eFormViewerCtrl.SetRunOption("READ_ONLY", "true");
          this.consentCommandCtrl.EnablePenDrawing = false;
          this.consentCommandCtrl.EnablePenConfig = false;
          this.consentCommandCtrl.onEnableDrawing(false);
          this.eFormViewerCtrl.EnableDrawing(false);
          this.consentCommandCtrl.SetEnablementExecuteWhenDualViewerActive(true);
        }
      }
      // 동의서 작성완료 후 이미지 저장
      if (eventCode.Equals("WRITTEN_IMAGE_FILE"))
      {
        // 확인 저장 시 이미지는 저장 함
        //if (!consentCommandCtrl.IsComplete)
        {
          this.OnWrittenImageFile(value);
        }
      }
      // 동의서 작성완료 후 Data XML 저장
      if (eventCode.Equals("DATA_XML_PATH"))
      {
        // [확인] 시에는 임시 저장만 한다.
        //if (consentCommandCtrl.IsComplete) {

        //    eFormViewerCtrl.TempSave();
        //}
        // 작성완료 버튼이 활성화 되어 있을 경우에만 작성완료 로직을 진행한다.
        //else if (this.consentCommandCtrl.getSaveButton()) {
        if (this.consentCommandCtrl.getSaveButton())
        {
          this.consentCommandCtrl.setSaveButton(false);
          this.OnWrittenDataXmlFile(value);
          this.consentCommandCtrl.setSaveButton(true);
          this.eFormViewerCtrl.ConfirmSave(true, "");

          //정상저장 후 다중서식 작업중일 경우 다음 동의서를 로드한다
          if (processResultValues.ContainsKey("OTHER_VALUE_1") && processResultValues["OTHER_VALUE_1"].ToString().Equals("1"))
          {
            if (multiParams != null)
            {
              showNextConsent();
            }
          }
        }
      }

      // 동의서 임시저장
      if (eventCode.Equals("TEMP_SAVE_PATH"))
      {
        // 임시저장 버튼이 활성화 되어 있을 경우에만 임시저장 로직을 진행한다.
        // Ku2.0 연동 시 임시저장 로직을 진행한다.
        // 작성 완료 시
        if (this.consentCommandCtrl.getTempSaveButton() || ConsentExecuteInfo["printYN"].Equals("Y") || consentCommandCtrl.IsComplete)
        {
          this.consentCommandCtrl.setTempSaveButton(false);
          this.OnWrittenTempSaveFile(value);

          if (!consentCommandCtrl.IsComplete)
          {
            this.consentCommandCtrl.setTempSaveButton(true);
          }

          this.eFormViewerCtrl.ConfirmSave(true, "");
        }

        //다중서식 작업중일 경우 다음 동의서를 출력한다
        if (multiParams != null)
        {
          showNextConsent();
        }
      }

      // 동의서 종이 출력
      if (eventCode.Equals("PRINT_COMPLETE"))
      {

        //this.consentCommandCtrl.OnPrint(value);
        // dbs227, 출력 로그 업데이트
        // 출력을 위한 호출일 경우 form 을 종료한다
        if (printConsentCount == 0 && ConsentExecuteInfo["printYN"].Equals("Y"))
        {
          Form parentForm = this.Parent as Form;
          if (parentForm != null)
          {
            parentForm.Close();
          }
        }
      }

      // dbs227, 동의서 프린트 실패
      if (eventCode.Equals("PRINT_FAIL") || eventCode.Equals("PRINT_CANCEL"))
      {
        // 추후 업무 협의 후 진행
        //consentCommandCtrl.erasePrintHistory();
      }

      //필수 항목 누락시 메시지 박스 호출
      if (eventCode.Equals("REQUIRED_INPUT_VIOLATION"))
      {
        this.consentCommandCtrl.OnRequiredInputViolation(value);
      }

      // 펜 그리기 모드 활성화 여부 제어
      if (eventCode.Equals("ENABLE_DRAWING"))
      {
        if (value.Equals("TRUE"))
        {
          this.consentCommandCtrl.onEnableDrawing(true);
        }
        else if (value.Equals("FALSE"))
        {
          this.consentCommandCtrl.onEnableDrawing(false);
        }
      }
      // 초기화 상태
      if (eventCode.Equals("INITIALIZE_STATE"))
      {
        if (value.Equals("FormViewInitialized"))
        {
          viewStatus = true;
        }
      }
      // 그외 이벤트
      // 동의서 저장 버튼 활셩화여부 제어
      // 동의서 임시서장 버튼 활성화 여부 반환(get)
      // 동의서 임시저장 버튼 활성화 여부 제어(set)
    }

    private void eFormViewerCtrl_VisibleChanged(object sender, EventArgs e)
    {
      if (this.eFormViewerCtrl.Visible)
      {
        if (this.OnVisibleEFormControl != null)
        {
          this.OnVisibleEFormControl.Invoke(this, new EventArgs());
        }
      }
      else
      {
        if (this.OnInvisibleEFormControl != null)
        {
          this.OnInvisibleEFormControl.Invoke(this, new EventArgs());
        }
      }
    }

    /// <summary>
    /// startFormCd 를 초기화 한다
    /// </summary>
    public void preParamClean()
    {
      this.ConsentExecuteInfo["startFormCd"] = string.Empty;
    }

    void IConsentMain.ReInitializeViewer()
    {
      if (eFormViewerCtrl.GetTotalPageCount() > 0)
      {
        eFormViewerCtrl.Visible = false;
        eFormViewerCtrl.CloseDualViewer();
        //this.eFormViewerCtrl.ReInitializeViewer();
      }

      this.viewStatus = false;
    }

    public void OnProcessCmdKey(Keys keyData)
    {

    }

    /// <summary>
    /// OCX 에서 넘겨 받은 FORMCD 리스트를 서버에서 조회해 온다
    /// </summary>
    private void GetConsentListByFormcd()
    {
      try
      {

        string[] formCdArr = ConsentExecuteInfo["formCd"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
        string[] ocrTagArr = ConsentExecuteInfo["ocrTag"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);

        printConsentCount = formCdArr.Length;

        for (int i = 0; i < formCdArr.Length; i++)
        {

          // 서버에서 목록 조회
          ConsentFormListVO vo = consentWebService.GetConsentByFormcd(formCdArr[i]
                                                                         , ConsentExecuteInfo["dutinstcd"]);

          if (vo == null/* || voArr.Length < 1*/)
          {
            throw new Exception("지정된 동의서를 찾을 수 없습니다.");
          }

          //ConsentBySearchVO vo = voArr[0];

          // 현재 preview 할동의서 정보 설정
          consentCommandCtrl.CurrentPreviewConsent = new PreviewConsent();

          consentCommandCtrl.CurrentPreviewConsent.formRid = vo.formRid.ToString();
          consentCommandCtrl.CurrentPreviewConsent.formGuid = vo.formGuid;
          consentCommandCtrl.CurrentPreviewConsent.formCd = vo.formCd.ToString();
          consentCommandCtrl.CurrentPreviewConsent.FormName = vo.formName;
          consentCommandCtrl.CurrentPreviewConsent.formPrintName = vo.formPrntNm;
          consentCommandCtrl.CurrentPreviewConsent.prntCnt = vo.printCnt;
          consentCommandCtrl.CurrentPreviewConsent.consentMstRid = "-1";
          consentCommandCtrl.CurrentPreviewConsent.consentState = string.Empty;
          consentCommandCtrl.CurrentPreviewConsent.inputId = consentCommandCtrl.CurrentEndUser.UserNo;
          consentCommandCtrl.CurrentPreviewConsent.inputNm = consentCommandCtrl.CurrentEndUser.UserName;
          consentCommandCtrl.CurrentPreviewConsent.ReissueConsentMstRid = 0;
          consentCommandCtrl.CurrentPreviewConsent.RewriteConsentMstRid = 0;
          consentCommandCtrl.CurrentPreviewConsent.ocrtagPrntyn = vo.ocrTagPrntYn;
          consentCommandCtrl.CurrentPreviewConsent.printOnly = vo.printOnly;
          consentCommandCtrl.CurrentPreviewConsent.opDiagName = vo.opDiagNm;
          consentCommandCtrl.CurrentPreviewConsent.opName = vo.opNm;
          consentCommandCtrl.CurrentPreviewConsent.userDrFlag = vo.userDrFlag;

          // 출력 연동이 아닌 경우
          if (ConsentExecuteInfo["printYN"].Equals("N"))
          {

            Dictionary<FOSParameter, string> globalParams = Common.CreateGlobalParamsDictionary(ConsentExecuteInfo["dutinstcd"]);

            List<string> formGuids = new List<string> {
                            consentCommandCtrl.CurrentPreviewConsent.formGuid
                        };

            consentCommandCtrl.SetPatientAndUser(globalParams);

            if (ocrTagArr.Length > 0)
            {
              globalParams[FOSParameter.OCRCode] = consentCommandCtrl.CurrentPreviewConsent.ocrCode = ocrTagArr[i]; // OCR 코드
            }
            else
            {
              globalParams[FOSParameter.OCRCode] = consentCommandCtrl.CurrentPreviewConsent.ocrCode = consentCommandCtrl.GetOcrCode(); // OCR 코드
            }

            int cnt = hospitalWebService.checkOcrDup(ConsentExecuteInfo["dutinstcd"], consentCommandCtrl.CurrentPreviewConsent.ocrCode);
            if(cnt > 0) {
              MessageBox.Show("OCRTAG 중복 발생입니다. 환자를 다시 선택하여 주십시요.");

              return;
            }

            // 임시저장의 경우 C 로 설정
            globalParams[FOSParameter.Device] = "C";
            globalParams[FOSParameter.PrintTime] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            globalParams[FOSParameter.SignTime] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            globalParams[FOSParameter.PrintIp] = ConsentExecuteInfo["printIP"];

            string fos = Common.GetFosString(formGuids
                                           , PluginExecuteInfo["formServiceUrl"]
                                           , globalParams
                                           , null
                                           , ConsentExecuteInfo["dutinstcd"]);

            // TODO 원무 인증 저장 pass
            // 원무 동의서는 인증저장을 하지 않는다
            shouldPassCertify = (this.consentWebService.getCertUseYn(consentCommandCtrl.CurrentPreviewConsent.formCd,
                ConsentExecuteInfo["dutinstcd"]) == "Y") ? true : false;
            // KU 시스템 연계시 동의서 종류와 상관 없이 인증버튼 활성화
            //if (shouldPassCertify)
            {
              // 인증저장 버튼을 활성화 한다
              consentCommandCtrl.SetEnableButtonsByCurrentConsent();
              //consentCommandCtrl.setSaveButton(true);
            }

            // 동의서 열기
            eFormViewerCtrl.OpenFos(fos);

            // 출력 히스토리 기록
            //this.consentCommandCtrl.OnPrint(vo.FormPrintName);
            //------------------------------
            // TODO 자동 듀얼뷰어 실행
            //Boolean openDualView = false;

            Boolean openDualView = (this.consentWebService.getDualViewMode(ConsentExecuteInfo["dutinstcd"],
                ConsentExecuteInfo["ipaddr"]) == "Y") ? true : false;
            if (openDualView)
            {
              consentCommandCtrl.RunConsentDualView();
            }
            //-------------------------------

            // dbs227 원무 인증 저장 pass
            if (shouldPassCertify)
            {

              //this.eFormViewerCtrl.SetZoomRate("wholepage");
              //consentCommandCtrl.setZoomRate(5);
            }

            if (ConsentExecuteInfo["tempSave"].Equals("N"))
            { // 지정된 동의서를 열기만 하는 경우

              // 여러 개의 formcd 를 받더라도 첫번째 것만 보여준다
              break;

            }
            else if (ConsentExecuteInfo["tempSave"].Equals("Y"))
            { // 임시 저장

              // 동의서 임시저장
              eFormViewerCtrl.TempSave();
            }
          }

          // 출력 연동
          if (ConsentExecuteInfo["printYN"].Equals("Y"))
          {

            int prntCnt = consentCommandCtrl.CurrentPreviewConsent.prntCnt;

            // 실행 파라미터에 PRINT_CNT 가 있고 0보다 클 경우 실행 파라미터를 우선으로 한다.
            if (!string.IsNullOrEmpty(ConsentExecuteInfo["printCount"]))
            {
              int.TryParse(ConsentExecuteInfo["printCount"], out prntCnt);
            }

            Dictionary<string, Dictionary<FOSParameter, string>> formParamsList = new Dictionary<string, Dictionary<FOSParameter, string>>();
            string[] formGuidList = new string[prntCnt];
            string sOcrCd = string.Empty;

            for (int j = 0; j < prntCnt; j++)
            {

              Dictionary<FOSParameter, string> formParams = Common.CreateGlobalParamsDictionary(ConsentExecuteInfo["dutinstcd"]);

              consentCommandCtrl.SetPatientAndUser(formParams);

              if (ocrTagArr.Length > 0)
              {
                formParams[FOSParameter.OCRCode] = consentCommandCtrl.CurrentPreviewConsent.ocrCode = ocrTagArr[i];
              }
              else
              {
                sOcrCd = formParams[FOSParameter.OCRCode] = consentCommandCtrl.CurrentPreviewConsent.ocrCode = consentCommandCtrl.GetOcrCode();
              }

              int cnt = hospitalWebService.checkOcrDup(ConsentExecuteInfo["dutinstcd"], consentCommandCtrl.CurrentPreviewConsent.ocrCode);
              if(cnt > 0) {
                MessageBox.Show("OCRTAG 중복 발생입니다. 환자를 다시 선택하여 주십시요.");

                return;
              }

              // 동일 서식을 2장 있을 출력할 경우, 2장째부터는 OCR 태그가 아닌 [환자보관용] 텍스트가 출력
              if (j > 0)
              {
                var ocrStr = this.consentWebService.getOcrString(consentCommandCtrl.CurrentPreviewConsent.formCd,
                    ConsentExecuteInfo["dutinstcd"]);
                if (ocrStr == null)
                {
                  ocrStr = "[환자 보관용]";
                }
                //ocrStr = (ocrStr == n) ? "[환자 보관용]" : ocrStr;
                //formParams[FOSParameter.OCRCode] = "[환자 보관용]";
                formParams[FOSParameter.OCRCode] = ocrStr;
              }

              formParams[FOSParameter.Device] = "P";
              formParams[FOSParameter.PrintTime] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
              formParams[FOSParameter.PrintIp] = ConsentExecuteInfo["printIP"];

              if (j == 1) formParams[FOSParameter.PrintComment] = Properties.Resources.msg_print_comment_2;
              else if (j == 2) formParams[FOSParameter.PrintComment] = Properties.Resources.msg_print_comment_3;

              formGuidList[j] = consentCommandCtrl.CurrentPreviewConsent.formGuid;

              formParamsList.Add((j + 1).ToString(), formParams);
            }

            string fos = Common.GetMultiFosString(formGuidList
                                                , PluginExecuteInfo["formServiceUrl"]
                                                , null
                                                , formParamsList
                                                , ConsentExecuteInfo["dutinstcd"]);

            String formPrintName = formParamsList["1"][FOSParameter.FormName];

            this.eFormViewerCtrl.OpenFos(fos);

            // 출력 히스토리 기록
            this.consentCommandCtrl.OnPrint(formPrintName);

            //int testpagecnt = this.eFormViewerCtrl.GetTotalPageCount();

            // dbs227, 출력 로그 업데이트
            // consent_mst 기록
            // InsertPrintData API 추가 후 기록
            //this.consentCommandCtrl.SaveDataForPrintedConsent(String.Empty);

            printConsentCount--;

            this.eFormViewerCtrl.PrintByPrinterName("");
          }
        }
      }
      catch (Exception ex)
      {
        MessageBox.Show(ex.ToString());
        initConsent();
        throw ex;
      }
    }

    public void initConsent()
    {
      consentCommandCtrl.CurrentPreviewConsent = null;
      patientInfoCtrl.SetConsentDocumentName("");
      eFormViewerCtrl.Visible = false;
      //eFormViewerCtrl.ReInitializeViewer();
      imageViewCtrl1.Hide();
    }

    private void btnHelp_Click(object sender, EventArgs e)
    {
      btnHelp.Enabled = false;
      Application.DoEvents();
      System.Diagnostics.Process.Start(@"https://ema031.knuh.kr:9091/doc/guide.pdf");
      btnHelp.Enabled = true;
    }

    int pageCnt = 0;
    Boolean printButtonClick = false;

    void IConsentMain.setPageCnt(int pageCnt)
    {
      this.pageCnt = pageCnt;
      //throw new NotImplementedException();
    }

    int IConsentMain.getPageCnt()
    {
      return this.pageCnt;
      //throw new NotImplementedException();
    }

    void IConsentMain.setPrintButton(bool flag)
    {
      this.printButtonClick = flag;
      //throw new NotImplementedException();
    }

    bool IConsentMain.getPrintButton()
    {
      return this.printButtonClick;
      //throw new NotImplementedException();
    }

    public void SendToMainControlMessage(object obj)
    {
      throw new NotImplementedException();
    }

    public void OnAlreadyExistsConsentForm(ref bool closeForm)
    {
      throw new NotImplementedException();
    }

    /// <summary>
    /// OCX 로 부터 넘겨 받은 파라미터를 decode(연속서식)
    /// </summary>
    /// <param name="pCallParm">EXEC_OPT 로 넘어온 파라미터 목록</param>
    /// <exception cref="Exception">CallParam 미전달</exception>
    private void InitMultiParamSetting(object pCallParm) {
      try {
        if (pCallParm != null) {
          Dictionary<string, object> callParam = pCallParm as Dictionary<string, object>;
          if (callParam != null && callParam.Count < 2) {
            if (callParam["CALL_PARAMS"] != null) {
              pCallParm = callParam["CALL_PARAMS"] as object;
            }
          }

          multiParams = new List<Dictionary<string, object>>();

          foreach (KeyValuePair<string, object> callKV in pCallParm as Dictionary<string, object>) {
            // 화면 설정 정보
            // 화면 설정 정보는 한번만 받으면 되기 때문에 받자마자 전역변수에 넣어준다
            if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "EXEC_OPT") {
              foreach (KeyValuePair<string, object> execKV in callKV.Value as Dictionary<string, object>) {
                string value = execKV.Value != null ? execKV.Value.ToString() : "";
                switch (execKV.Key) {
                  case "USE_LIST_VIEW":
                    ConsentExecuteInfo["useListView"] = "N";
                    break;
                  case "PTNT_LIST_VIEW":
                    ConsentExecuteInfo["patientListView"] = "N";
                    break;
                  case "START_FORM_CD":
                    ConsentExecuteInfo["startFormCd"] = value;
                    break;
                  case "PTNT_ACT":
                    ConsentExecuteInfo["printAct"] = value;
                    break;
                  case "PRINT_LIST":
                    if (execKV.Value != null) {
                      if (execKV.Value is List<object> PatientList && PatientList.Count > 0) {
                        PrintInfoList = new List<ConsentFormListVO>();

                        ConsentFormListVO consentVO = new ConsentFormListVO();

                        for (int i = 0; i < PatientList.Count; i++) {
                          consentVO = new ConsentFormListVO {
                            printCnt = -1
                          };

                          foreach (KeyValuePair<string, object> callOrderKV in PatientList[i] as Dictionary<string, object>) {
                            if (callOrderKV.Key != null && !string.IsNullOrEmpty(callOrderKV.Key.ToString()) && callOrderKV.Value != null) {
                              if (callOrderKV.Key.ToString() == "START_FORM_CD") consentVO.formCd = callOrderKV.Value.ToString(); // 출력 서식코드
                              if (callOrderKV.Key.ToString() == "PTNT_NO") consentVO.pid = callOrderKV.Value.ToString(); // 환자번호
                              if (callOrderKV.Key.ToString() == "VISIT_TYPE") consentVO.ordType = callOrderKV.Value.ToString(); // 내원구분
                              if (callOrderKV.Key.ToString() == "CLN_DATE") consentVO.inDd = callOrderKV.Value.ToString(); // 진료일자
                              if (callOrderKV.Key.ToString() == "CLN_DEPT") consentVO.ordDeptCd = callOrderKV.Value.ToString(); // 진료과
                              if (callOrderKV.Key.ToString() == "PRINT_CNT") {
                                int.TryParse(callOrderKV.Value.ToString(), out int PrntCnt);
                                consentVO.printCnt = PrntCnt; // 출력 카운트
                              }
                              if (callOrderKV.Key.ToString() == "CRETNO") {
                                int.TryParse(callOrderKV.Value.ToString(), out int cretno);
                                consentVO.cretNo = cretno; // 차트번호
                              }
                            }
                          }
                          PrintInfoList.Add(consentVO);
                        }
                        if (execKV.Value != null) ConsentExecuteInfo["printList"] = PrintInfoList.Count.ToString(); // 출력 데이터
                      }
                    }
                    break;
                  case "FORMCD":
                    ConsentExecuteInfo["formCd"] = value;
                    break;
                  case "OCRTAG":
                    ConsentExecuteInfo["ocrTag"] = value;
                    break;
                  case "TEMP_SAVE":
                    ConsentExecuteInfo["tempSave"] = value;
                    break;
                  case "PRINT_YN":
                    ConsentExecuteInfo["printYN"] = value;
                    break;
                  case "PRINT_CNT":
                    ConsentExecuteInfo["printCount"] = value;
                    break;
                  case "SYSINSTNM":
                    if (execKV.Value != null) {
                      string instCd = string.Empty;

                      instCd = execKV.Value.ToString().Contains("본원") ? "031" : execKV.Value.ToString().Contains("칠곡") ? "032" : string.Empty;
                      instCd += execKV.Value.ToString().Contains("교육") ? "edu" : string.Empty;
                      //instCd = "Dev";

                      ConsentExecuteInfo["sysInstNm"] = instCd;
                    }
                    break;
                  case "READONLY":
                    ConsentExecuteInfo["readOnly"] = value;
                    break;
                  default:
                    break;
                }
              }
            }

            //연속 서식 파라미터 디코드
            //연속 서식을 위한 파라미터들은 배열 형태로 들어오기 때문에 dictionary 배열로 디코드 한 후에
            //서식을 로드할 때 하나씩 불러와 전역변수에 넣어준다
            else if (callKV.Key != null && !string.IsNullOrEmpty(callKV.Key.ToString()) && callKV.Key.ToString() == "PARAMS") {
              List<object> paramsList = callKV.Value as List<object>;
              if (paramsList == null) {
                throw new Exception("InitMultiParamSetting 오류");
              }

              int multiParamCount = 0;
              foreach (Dictionary<string, object> item in paramsList) {
                multiParams.Add(new Dictionary<string, object>());

                if (item != null && item.ContainsKey("PATIENT_INFO")) {
                  //환자정보
                  multiParams[multiParamCount].Add("PATIENT_INFO", new Dictionary<string, object>());
                  Dictionary<string, object> multiParamPatient = (multiParams[multiParamCount])["PATIENT_INFO"] as Dictionary<string, object>;

                  multiParamPatient.Add("PTNT_NO", "");
                  multiParamPatient.Add("VISIT_TYPE", "");
                  multiParamPatient.Add("CLN_DEPT", "");
                  multiParamPatient.Add("CLN_DATE", "");
                  multiParamPatient.Add("CRETNO", "");
                  multiParamPatient.Add("CLN_DX_NM", "");
                  multiParamPatient.Add("OPRSRVNO", "");

                  foreach (KeyValuePair<string, object> patientItem in item["PATIENT_INFO"] as Dictionary<string, object>) {
                    string value = patientItem.Value != null ? patientItem.Value.ToString() : "";

                    switch (patientItem.Key) {
                      case "PTNT_NO":
                        multiParamPatient["PTNT_NO"] = value;
                        break;

                      case "VISIT_TYPE":
                        multiParamPatient["VISIT_TYPE"] = value;
                        break;

                      case "CLN_DEPT":
                        multiParamPatient["CLN_DEPT"] = value;
                        break;

                      case "CLN_DATE":
                        multiParamPatient["CLN_DATE"] = value;
                        break;

                      case "CRETNO":
                        multiParamPatient["CRETNO"] = value;
                        break;

                      case "CLN_DX_NM":
                        multiParamPatient["CLN_DX_NM"] = value;
                        break;

                      case "OPRSRVNO":
                        multiParamPatient["OPRSRVNO"] = value;
                        break;

                      default:
                        break;
                    }
                  }
                }

                if (item.ContainsKey("USER_INFO")) {
                  //사용자 정보
                  multiParams[multiParamCount].Add("USER_INFO", new Dictionary<string, object>());
                  Dictionary<string, object> multiParamUser = (multiParams[multiParamCount])["USER_INFO"] as Dictionary<string, object>;

                  multiParamUser.Add("USER_ID", "");
                  multiParamUser.Add("DUTINSTCD", "");
                  multiParamUser.Add("USER_NAME", "");
                  multiParamUser.Add("USER_DEPTCD", "");
                  multiParamUser.Add("USER_DEPTNM", "");

                  foreach (KeyValuePair<string, object> userItem in item["USER_INFO"] as Dictionary<string, object>) {
                    string value = userItem.Value != null ? userItem.Value.ToString() : "";
                    switch (userItem.Key) {
                      case "USER_ID":
                        multiParamUser["USER_ID"] = value;
                        break;

                      case "DUTINSTCD":
                        multiParamUser["DUTINSTCD"] = value;
                        break;

                      case "USER_NAME":
                        multiParamUser["USER_NAME"] = value;
                        break;

                      case "USER_DEPTCD":
                        multiParamUser["USER_DEPTCD"] = value;
                        break;

                      case "USER_DEPTNM":
                        multiParamUser["USER_DEPTNM"] = value;
                        break;

                      default:
                        break;
                    }
                  }
                }

                if (item.ContainsKey("PAM_INFO")) {
                  //원무
                  multiParams[multiParamCount].Add("PAM_INFO", new Dictionary<string, object>());
                  Dictionary<string, object> multiParamPam = (multiParams[multiParamCount])["PAM_INFO"] as Dictionary<string, object>;

                  multiParamPam.Add("SPEC_DR_YN", "");
                  multiParamPam.Add("CONT_START_DT", "");
                  multiParamPam.Add("CONT_END_DT", "");
                  multiParamPam.Add("ROOM_CAPA", "");
                  multiParamPam.Add("CONT_TELNO", "");
                  multiParamPam.Add("CONT_STAFF1", "");
                  multiParamPam.Add("CONT_STAFF2", "");
                  multiParamPam.Add("CONT_STAFF3", "");
                  multiParamPam.Add("CARD_NO", "");
                  multiParamPam.Add("TAG1", "");
                  multiParamPam.Add("TAG2", "");
                  multiParamPam.Add("TAG3", "");
                  multiParamPam.Add("TAG4", "");
                  multiParamPam.Add("TAG5", "");
                  multiParamPam.Add("TAG6", "");
                  multiParamPam.Add("TAG7", "");
                  multiParamPam.Add("TAG8", "");
                  multiParamPam.Add("TAG9", "");
                  multiParamPam.Add("TAG10", "");

                  foreach (KeyValuePair<string, object> pamItem in item["PAM_INFO"] as Dictionary<string, object>) {

                    string value = pamItem.Value != null ? pamItem.Value.ToString() : "";
                    switch (pamItem.Key) {
                      case "SPEC_DR_YN":
                        multiParamPam["SPEC_DR_YN"] = value;
                        break;

                      case "CONT_START_DT":
                        multiParamPam["CONT_START_DT"] = value;
                        break;

                      case "CONT_END_DT":
                        multiParamPam["CONT_END_DT"] = value;
                        break;

                      case "ROOM_CAPA":
                        multiParamPam["ROOM_CAPA"] = value;
                        break;

                      case "CONT_TELNO":
                        multiParamPam["CONT_TELNO"] = value;
                        break;

                      case "CONT_STAFF1":
                        multiParamPam["CONT_STAFF1"] = value;
                        break;

                      case "CONT_STAFF2":
                        multiParamPam["CONT_STAFF2"] = value;
                        break;

                      case "CONT_STAFF3":
                        multiParamPam["CONT_STAFF3"] = value;
                        break;

                      case "CARD_NO":
                        multiParamPam["CARD_NO"] = value;
                        break;
                      case "TAG1":
                        multiParamPam["TAG1"] = value;
                        break;
                      case "TAG2":
                        multiParamPam["TAG2"] = value;
                        break;
                      case "TAG3":
                        multiParamPam["TAG3"] = value;
                        break;
                      case "TAG4":
                        multiParamPam["TAG4"] = value;
                        break;
                      case "TAG5":
                        multiParamPam["TAG5"] = value;
                        break;
                      case "TAG6":
                        multiParamPam["TAG6"] = value;
                        break;
                      case "TAG7":
                        multiParamPam["TAG7"] = value;
                        break;
                      case "TAG8":
                        multiParamPam["TAG8"] = value;
                        break;
                      case "TAG9":
                        multiParamPam["TAG9"] = value;
                        break;
                      case "TAG10":
                        multiParamPam["TAG10"] = value;
                        break;
                      default:
                        break;
                    }
                  }
                }
                if (item.ContainsKey("CONSENT_DATA")) {
                  //동의서 데이터
                  multiParams[multiParamCount].Add("CONSENT_DATA", new Dictionary<string, object>());
                  Dictionary<string, object> multiParamConsent = (multiParams[multiParamCount])["CONSENT_DATA"] as Dictionary<string, object>;

                  multiParamConsent.Add("ocrTag", "");
                  multiParamConsent.Add("formCd", "");
                  multiParamConsent.Add("tempsaveYn", "");

                  foreach (KeyValuePair<string, object> consentItem in item["CONSENT_DATA"] as Dictionary<string, object>) {
                    string value = consentItem.Value != null ? consentItem.Value.ToString() : "";
                    switch (consentItem.Key) {
                      case "ocrTag":
                        multiParamConsent["ocrTag"] = value;
                        break;
                      case "formCd":
                        multiParamConsent["formCd"] = value;
                        break;
                      case "tempsaveYn":
                        multiParamConsent["tempsaveYn"] = value;
                        break;
                      default:
                        break;
                    }
                  }
                  
                }

                multiParamCount++;
              }
            }
          }
          multiParams.Add(new Dictionary<string, object>() { ["PAGE_COUNT"] = 0 });
        } else {
          throw new Exception("CallParam 미전달");
        }

        // IP 주소 확인
        string printIp = string.Empty;
        foreach (System.Net.IPAddress ip in System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName())) {
          if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) {
            printIp = ip.ToString();
            break;
          }
        }

        // dbs227, 경북대학교병원 ip address 기록
        ConsentExecuteInfo["ipaddr"] = printIp;

        if (!printIp.Equals(string.Empty)) {
          string[] ipArr = printIp.Split(new string[] { "." }, StringSplitOptions.RemoveEmptyEntries);
          if (ipArr.Length == 4) {
            printIp = string.Format("{0}.{1}", ipArr[2], ipArr[3]);
          } else {
            printIp = string.Empty;
          }
        }

        ConsentExecuteInfo["printIP"] = printIp;
      } catch (Exception ex) {
        throw ex;
      }
    }

    /// <summary>
    /// 연속서식을 위한 배열 데이터를 꺼내서 전역변수에 할당한다
    /// </summary>
    /// <param name="page">받아올 배열의 인덱스</param>
    private void setConsentViewMultiParams(int page) {
      Dictionary<string, object> currentParam = multiParams[page];
      setGlobalValueWithMultiParam(currentParam);
    }

    /// <summary>
    /// 파라미터를 받아 전역변수에 할당
    /// </summary>
    /// <param name="pCallParm">EXEC_OPT 로 넘어온 파라미터 목록</param>
    /// <exception cref="Exception">CallParam 미전달</exception>
    private void setGlobalValueWithMultiParam(object pCallParm) {
      try {
        if (pCallParm != null) {
          Dictionary<string, object> callParam = pCallParm as Dictionary<string, object>;
          if (callParam != null && callParam.Count < 2) {
            if (callParam["CALL_PARAMS"] != null) {
              pCallParm = callParam["CALL_PARAMS"] as object;
            }
          }

          foreach (KeyValuePair<string, object> callKV in pCallParm as Dictionary<string, object>) {
            // 사용자 정보
            if (callKV.Key != null && callKV.Key.ToString() == "USER_INFO") {
              foreach (KeyValuePair<string, object> userKV in callKV.Value as Dictionary<string, object>) {

                string value = userKV.Value != null ? userKV.Value.ToString() : "";
                switch (userKV.Key.ToString()) {
                  case "USER_ID":
                    ConsentExecuteInfo["userNo"] = value;
                    ConsentExecuteInfo["loginUserNo"] = value;
                    break;
                  case "DUTINSTCD":
                    ConsentExecuteInfo["dutinstcd"] = value;
                    break;
                  case "USER_NAME":
                    ConsentExecuteInfo["userName"] = value;
                    ConsentExecuteInfo["loginUserName"] = value;
                    break;
                  case "USER_DEPTCD":
                    ConsentExecuteInfo["userDeptCd"] = value;
                    break;
                  case "USER_DEPTNM":
                    ConsentExecuteInfo["userDeptName"] = value;
                    break;
                  default:
                    break;
                }
              }
            }

            // 환자 정보
            if (callKV.Key != null && callKV.Key.ToString() == "PATIENT_INFO") {
              foreach (KeyValuePair<string, object> patientKV in callKV.Value as Dictionary<string, object>) {

                string value = patientKV.Value != null ? patientKV.Value.ToString() : "";
                switch (patientKV.Key.ToString()) {
                  case "PTNT_NO":
                    ConsentExecuteInfo["patientNo"] = value;
                    break;
                  case "VISIT_TYPE":
                    ConsentExecuteInfo["visitType"] = value;
                    break;
                  case "CLN_DEPT":
                    ConsentExecuteInfo["clnDept"] = value;
                    break;
                  case "CLN_DATE":
                    ConsentExecuteInfo["clnDate"] = value;
                    break;
                  case "CRETNO":
                    ConsentExecuteInfo["cretno"] = value;
                    break;
                  case "CLN_DX_NM":
                    ConsentExecuteInfo["clnDxNm"] = value;
                    break;
                  case "OPRSRVNO":
                    ConsentExecuteInfo["opRsrvNo"] = value;
                    break;
                  default:
                    break;
                }
              }
            }

            // 원무
            if (callKV.Key != null && callKV.Key.ToString() == "PAM_INFO") {
              foreach (KeyValuePair<string, object> pamKV in callKV.Value as Dictionary<string, object>) {

                string value = pamKV.Value != null ? pamKV.Value.ToString() : "";
                switch (pamKV.Key.ToString()) {
                  case "SPEC_DR_YN":
                    ConsentExecuteInfo["SpecDoctorYN"] = value;
                    break;
                  case "CONT_START_DT":
                    ConsentExecuteInfo["ContStartDate"] = value;
                    break;
                  case "CONT_END_DT":
                    ConsentExecuteInfo["ContEndDate"] = value;
                    break;
                  case "ROOM_CAPA":
                    ConsentExecuteInfo["RoomCapa"] = value;
                    break;
                  case "CONT_TELNO":
                    ConsentExecuteInfo["ContTelNo"] = value;
                    break;
                  case "CONT_STAFF1":
                    ConsentExecuteInfo["ContStaff1Name"] = value;
                    break;
                  case "CONT_STAFF2":
                    ConsentExecuteInfo["ContStaff2Name"] = value;
                    break;
                  case "CONT_STAFF3":
                    ConsentExecuteInfo["ContStaff3Name"] = value;
                    break;
                  case "CARD_NO":
                    ConsentExecuteInfo["CardNo"] = value;
                    break;
                  case "TAG1":
                    ConsentExecuteInfo["tag1"] = value;
                    break;
                  case "TAG2":
                    ConsentExecuteInfo["tag2"] = value;
                    break;
                  case "TAG3":
                    ConsentExecuteInfo["tag3"] = value;
                    break;
                  case "TAG4":
                    ConsentExecuteInfo["tag4"] = value;
                    break;
                  case "TAG5":
                    ConsentExecuteInfo["tag5"] = value;
                    break;
                  case "TAG6":
                    ConsentExecuteInfo["tag6"] = value;
                    break;
                  case "TAG7":
                    ConsentExecuteInfo["tag7"] = value;
                    break;
                  case "TAG8":
                    ConsentExecuteInfo["tag8"] = value;
                    break;
                  case "TAG9":
                    ConsentExecuteInfo["tag9"] = value;
                    break;
                  case "TAG10":
                    ConsentExecuteInfo["tag10"] = value;
                    break;
                  default:
                    break;
                }
              }
            }
          }
        } else {
          throw new Exception("CallParam 미전달");
        }
      } catch (Exception ex) {
        throw ex;
      }
    }

    /// <summary>
    /// 파라미터 배열의 인덱스를 가지고 해당 파라미터에 대한 동의서를 띄운다
    /// </summary>
    /// <param name="page"></param>
    private void showConsentView(int page) {
      Dictionary<string, object> currentParam = multiParams[page] as Dictionary<string, object>;
      if (!(currentParam != null && currentParam.ContainsKey("CONSENT_DATA"))) {
        return;
      }

      setConsentViewMultiParams(page);
      patientInfoCtrl.OnRefeashPartControls("");

      //파라미터를 가지고 동의서 정보를 만든다
      if (currentParam["CONSENT_DATA"] is Dictionary<string, object> currentConsent) {
        //ConsentFormListVO consent = new ConsentFormListVO();
        ConsentFormListVO consent = consentWebService.GetConsentByFormcd(currentConsent["formCd"].ToString(), ConsentExecuteInfo["dutinstcd"].ToString());
        if (consent == null)
        {
          MessageBox.Show("동의서 정보가 잘못되었습니다.");
          return;
        }

        consent.createUserId = ConsentExecuteInfo["loginUserNo"];
        consent.createUserName = ConsentExecuteInfo["loginUserName"];
        consent.ocrTag = currentConsent["ocrTag"] != null ? currentConsent["ocrTag"].ToString() : "";
        consent.pid = ConsentExecuteInfo["patientNo"] != null ? ConsentExecuteInfo["patientNo"].ToString() : "";
        consent.inDd = ConsentExecuteInfo["clnDate"] != null ? ConsentExecuteInfo["clnDate"].ToString() : "";
        consent.ordType = ConsentExecuteInfo["visitType"] != null ? ConsentExecuteInfo["visitType"].ToString() : "";
        consent.ordDeptCd = ConsentExecuteInfo["clnDept"] != null ? ConsentExecuteInfo["clnDept"].ToString() : "";

        if (ConsentExecuteInfo["cretno"] != null)
        {
          consent.cretNo = Int32.TryParse(ConsentExecuteInfo["cretno"], out int res) ? res : 0;
        }
        consent.opRsrvNo = ConsentExecuteInfo["opRsrvNo"] != null ? ConsentExecuteInfo["opRsrvNo"].ToString() : "";
        
        executePreviewConsent(consent);

      } else {
        return;
      }
    }
    private void showNextConsent()
    {

      //현재 동의서가 몇번째인지 받아온다
      Dictionary<string, object> currentPageParam = ((Dictionary<string, object>)multiParams[multiParams.Count - 1]);
      int page = Int32.TryParse(currentPageParam["PAGE_COUNT"].ToString(), out int cnt) ? cnt : -1;
      currentPageParam["PAGE_COUNT"] = Int32.Parse(currentPageParam["PAGE_COUNT"].ToString()) + 1;
      if (page >= 0)
      {
        //마지막 서식이면 종료한다.
        if (multiParams.Count - 2 == page)
        {
          Form parentForm = this.Parent as Form;
          if (parentForm != null)
          {
            parentForm.Close();
          }
        }
        page++;
        showConsentView(page);
      }
    }


    private void executePreviewConsent(ConsentFormListVO vo)
    {
      Cursor currentCursor = this.Cursor;
      this.Cursor = Cursors.WaitCursor;

      consentCommandCtrl.CurrentPreviewConsent = new PreviewConsent
      {
        formRid = vo.formRid.ToString(),
        formGuid = vo.formGuid,
        formCd = vo.formCd.ToString(),
        FormName = vo.formName,
        formPrintName = vo.formPrntNm,
        prntCnt = vo.printCnt,
        consentMstRid = vo.consentMstRid.ToString(),
        consentStateEngnm = vo.consentStateEng,
        orderNo = 0,
        ocrCode = vo.ocrTag,
        inputId = vo.createUserId,
        inputNm = vo.createUserName,
        ReissueConsentMstRid = IsConsentStatePrintOut(vo) ? vo.consentMstRid : 0,
        RewriteConsentMstRid = !IsConsentStateUnfinished(vo) ? vo.consentMstRid : 0,
        ordType = vo.ordType,
        ocrtagPrntyn = vo.ocrTagPrntYn,
        userDrFlag = vo.userDrFlag,
        printOnly = vo.printOnly,
        opDiagName = vo.opDiagNm,
        consentState = vo.consentStateEng,
        opName = vo.opNm
      };

      try
      {
        patientInfoCtrl.SetConsentDocumentName(vo.formName);

        //동의서와 유저 상태에 따라 상단의 저장버튼을 활성화시키는 구문
        if (consentCommandCtrl.CurrentTargetPatient.VisitType.Equals("O"))
        {
          consentCommandCtrl.setCompleteSaveButton(true);
        }
        else
        {
          if (ConsentMainControl.SETTING_DATA["ELECTR_CMP"].Equals("Y") && consentCommandCtrl.CurrentEndUser.JobKindCd.Substring(0, 2).Equals("03"))
          {
            consentCommandCtrl.setCompleteSaveButton(true);
          }
          else
          {
            consentCommandCtrl.setCompleteSaveButton(false);
          }

        }

        if (!consentCommandCtrl.CurrentEndUser.JobKindCd.Substring(0, 2).Equals("03"))
        {
          consentCommandCtrl.setCompleteSaveButton(false);
        }

        consentCommandCtrl.PreviewConsent(this);

        //임시저장 활성화 여부
        consentCommandCtrl.setToolstripEnabled(true);
        Dictionary<string, object> consentData = getParamsWithIndex(getCurrentConsentPage())["CONSENT_DATA"] as Dictionary<string, object>;
        if (consentData.ContainsKey("tempsaveYn"))
        {
          if (consentData["tempsaveYn"].ToString().Equals("Y"))
          {
            consentCommandCtrl.setTempSaveButton(true);
          }
          else
          {
            consentCommandCtrl.setTempSaveButton(false);
          }
        }
      }
      catch
      {
        
      }
      finally
      {
        this.Cursor = currentCursor;
      }
    }

    #region ConsentState 확인
    private static bool IsConsentStateTempSave(ConsentFormListVO vo)
    {
      if (vo.consentStateEng.ToUpper().Equals("TEMP") || vo.consentStateEng.ToUpper().Equals("VERBAL"))
      {
        return true;
      }
      return false;
    }

    private static bool IsConsentStatePrintOut(ConsentFormListVO vo)
    {
      return vo.consentStateEng.ToUpper().Equals("PAPER_OUT");
    }

    private static bool IsConsentStateElectronicComplete(ConsentFormListVO vo)
    {
      return vo.consentStateEng.ToUpper().Equals("ELECTR_CMP");
    }

    private static bool IsConsentStateCertifyComplete(ConsentFormListVO vo)
    {
      return vo.consentStateEng.ToUpper().Equals("CERTIFY_CMP");
    }

    private static bool IsConsentStateUnfinished(ConsentFormListVO vo)
    {
      return vo.consentStateEng.ToUpper().Equals("UNFINISHED");
    }
    #endregion

    /// <summary>
    /// 다중 서식을 받아왔을 때 현재 보고있는 서식의 인덱스를 반환한다
    /// </summary>
    /// <returns></returns>
    private int getCurrentConsentPage()
    {
      int page = 0;
      if (multiParams != null)
      {
        Dictionary<string, object> pageParam = multiParams[multiParams.Count - 1];
        if (pageParam.ContainsKey("PAGE_COUNT"))
        {
          page = Int32.TryParse(pageParam["PAGE_COUNT"].ToString(), out int pageNumber) ? pageNumber : -1;
        }
      }
      return page;
    }

    /// <summary>
    /// 다중 서식의 특정 페이지에 대한 파라미터를 불러온다
    /// </summary>
    /// <param name="page"></param>
    /// <returns></returns>
    private Dictionary<string, object> getParamsWithIndex(int page)
    {
      Dictionary<string, object> returnParam = null;
      if (multiParams != null)
      {
        returnParam = multiParams[page];
      }

      return returnParam;
    }

    public void showNextPreview()
    {
      showNextConsent();
    }
  }
}