package com.ufsoft.iufo.inputplugin.key;

import java.util.HashMap;
import java.util.Map;

import javax.swing.SwingUtilities;

import nccloud.commons.lang.StringUtils;

import com.ufida.dataset.Context;
import com.ufida.dataset.IContext;
import com.ufida.iufo.table.exarea.ExtendAreaCell;
import com.ufida.zior.view.Editor;
import com.ufsoft.iufo.fmtplugin.BDContextKey;
import com.ufsoft.iufo.fmtplugin.datapreview.ReportDataPreviewDesigner;
import com.ufsoft.iufo.fmtplugin.dynarea.DynAreaUtil;
import com.ufsoft.iufo.fmtplugin.dynarea.DynamicAreaModel;
import com.ufsoft.iufo.fmtplugin.formatcore.IUfoContextKey;
import com.ufsoft.iufo.fmtplugin.formula.FormulaModel;
import com.ufsoft.iufo.fmtplugin.formula.UfoFmlExecutor;
import com.ufsoft.iufo.fmtplugin.key.KeyFilterCondParser;
import com.ufsoft.iufo.fmtplugin.key.KeyFilterParsedContent;
import com.ufsoft.iufo.fmtplugin.key.KeywordModel;
import com.ufsoft.iufo.inputplugin.biz.formulatracenew.UfoFormulaTraceBizHelper;
import com.ufsoft.report.ReportContextKey;
import com.ufsoft.report.StateUtil;
import com.ufsoft.table.AreaPosition;
import com.ufsoft.table.CellPosition;
import com.ufsoft.table.CellsModel;
import com.ufsoft.table.CellsPane;
import com.ufsoft.table.re.IInputEditor;

import nc.vo.iufo.data.MeasurePubDataVO;
import nc.vo.iufo.keydef.KeyVO;

import nc.pub.iufo.basedoc.IDName;
import nc.desktop.ui.WorkbenchEnvironment;

import nc.ui.bd.intdata.scheme.model.DIRepItemRefModel;
import nc.ui.iufo.ClientEnv;
import nc.ui.iufo.input.edit.base.AbstractRepDataRefEditor;
import nc.ui.iufo.input.edit.base.IRepDataEditor;
import nc.ui.iufo.input.key.AllUnitRefParam;
import nc.ui.iufo.input.key.ComOrgRefParam;
import nc.ui.iufo.input.key.IUFOOrgRefParam;
import nc.ui.iufo.input.key.IUFOUnitOrgRefParam;
import nc.ui.iufo.input.key.OrgInputEditor;
import nc.ui.iufo.input.key.RefInputEditor;
import nc.ui.iufo.input.key.UFOCUnitOrgRefParam;
import nc.ui.iufo.input.key.V5KeyRefInputEditor;
import nc.ui.iufo.input.ufoe.comp.AbsRepDataEditorInComb;
import nc.ui.pub.beans.UIRefPane;
import nc.ui.pub.beans.ValueChangedEvent;
import nc.ui.pub.beans.ValueChangedListener;

import nc.util.iufo.repdata.v5.IUFOKeyWordFillEnv;
import nc.util.iufo.repdata.v5.IUFORepDataFromV5Util;

public class KeyCodeRefEditor extends AbstractRepDataRefEditor implements
    IUfoContextKey {

  public KeyCodeRefEditor() {
    super();
  }

  @Override
  protected IInputEditor getInputEditor(final CellsPane table, int row, int col) {
    CellPosition cellPos = CellPosition.getInstance(row, col);
    KeyFmt fmt = DynAreaUtil.getKeyFmt(cellPos, table.getDataModel());
    IInputEditor keyEditor = null;
    Editor editor =
        (Editor) SwingUtilities.getAncestorOfClass(Editor.class, table);
    IContext context = editor.getContext();
    String strRepOrgPK =
        context.getAttribute(BDContextKey.CUR_REPORG_PK) == null ? null
            : (String) context.getAttribute(BDContextKey.CUR_REPORG_PK);
    String setRepPK =
        context.getAttribute(IUfoContextKey.KEY_CURREDITOR_REPPK) == null ? null
            : (String) context
                .getAttribute(IUfoContextKey.KEY_CURREDITOR_REPPK);
    if (StringUtils.isEmpty(setRepPK)) {
      setRepPK =
          context.getAttribute(ReportContextKey.REPORT_PK) == null ? null
              : (String) context.getAttribute(ReportContextKey.REPORT_PK);
    }
    IUFOKeyWordFillEnv env =
        IUFORepDataFromV5Util.initDIDynAreaEnv(setRepPK, strRepOrgPK,
            DynAreaUtil.getKeywordModel(table.getDataModel())
                .getSubTableKeyVO().toArray(new KeyVO[0]));
    if (fmt.getType() == KeyFmt.TYPE_DIC_UNIT
        || fmt.getType() == KeyFmt.TYPE_UNIT
        || "b0969fd4-2923-43c2-888a-c9fa4a25a528".equals(fmt.getRefCodePK())) {// tianchuan
                                                                               // 2013.12.3
                                                                               // 报表组织的PK也一并处理
      String strRepMngStructPK =
          context.getAttribute(BDContextKey.CUR_REPMNGSTRUCT_PK) == null ? null
              : (String) context.getAttribute(BDContextKey.CUR_REPMNGSTRUCT_PK);
      String strOrgType = (String) context.getAttribute(BDContextKey.ORG_TYPE);

      if (strRepMngStructPK == null) {
        keyEditor = new OrgInputEditor(new AllUnitRefParam(), true);
      }
      else if (strOrgType != null) {
        keyEditor =
            new OrgInputEditor(new ComOrgRefParam(null, strOrgType), true);
      }
      else if (fmt.getType() == KeyFmt.TYPE_DIC_UNIT
          || "b0969fd4-2923-43c2-888a-c9fa4a25a528".equals(fmt.getRefCodePK())) {// tianchuan
                                                                                 // 2013.12.3
                                                                                 // 报表组织的PK也一并处理
        if ("true".equals(context.getAttribute("key_is_hbbbdata"))) {
          strRepMngStructPK =
              (String) ((AbsRepDataEditorInComb) table.getParent().getParent()
                  .getParent()).getMainboard().getContext()
                  .getAttribute(BDContextKey.CUR_REPMNGSTRUCT_PK);
          keyEditor =
              new OrgInputEditor(new UFOCUnitOrgRefParam(strRepOrgPK,
                  strRepMngStructPK), true);
        }
        else {
          Map<KeyVO, String> keyValMap = new HashMap<KeyVO, String>();
          MeasurePubDataVO pubDateVO =
              (MeasurePubDataVO) context
                  .getAttribute(IUfoContextKey.MEASURE_PUB_DATA_VO);
          KeyVO keyVO = pubDateVO.getKeyGroup().getTimeKey();
          String inputTime =
              keyVO != null ? pubDateVO.getKeywordByPK(pubDateVO.getKeyGroup()
                  .getTimeKey().getPk_keyword()) : WorkbenchEnvironment
                  .getInstance().getBusiDate().toString();
          keyValMap.put(keyVO, inputTime);
          keyEditor =
              new OrgInputEditor(new IUFOUnitOrgRefParam(strRepOrgPK,
                  strRepMngStructPK, keyValMap), true);
        }
      }
      else {
        keyEditor =
            new OrgInputEditor(new IUFOOrgRefParam(strRepOrgPK,
                strRepMngStructPK), true);
      }
    }
    // 区分当前编辑的关键字是否引用的V5档案，并且报表关联的整合方案是从V5取数
    else if (IUFORepDataFromV5Util.isNeedGetKeyValFromV5(fmt.getKeyPK(), env)) {
      keyEditor =
          new V5KeyRefInputEditor(fmt.getRefCodePK(), setRepPK, strRepOrgPK,
              env.getKeyValueFromV5Ds(fmt.getKeyPK()));
    }
    else {
//      ClientEnv.getInstance().setAttribute("ReportItemSystem",
//          IUFORepDataFromV5Util.getReportItemSys(setRepPK));
      keyEditor = new RefInputEditor(true, fmt.getRefCodePK(), false);
    }
    UIRefPane refPane = (UIRefPane) keyEditor.getComponent();

    // 将当前组织设置到参照模型中
    MeasurePubDataVO measPubVO =
        (MeasurePubDataVO) context
            .getAttribute(IUfoContextKey.MEASURE_PUB_DATA_VO);
    if (measPubVO != null) {
      String orgPk = measPubVO.getUnitPK();
      if (orgPk != null && orgPk.length() > 0) {
        refPane.getRefModel().setPk_org(orgPk);
      }
    }

    // 向参照编辑器中设置筛选条件
    this.setFilterCondToRefEditor(table, row, col, refPane, (Context) context);

    // @edit by wuyongc at 2013-3-6,下午1:43:25
    // 多选择的关键字值个数进行监听，如果是多选，则动态区增加多条记录.
    refPane.addValueChangedListener(new ValueChangedListener() {

      @Override
      public void valueChanged(ValueChangedEvent event) {
        if (event.getNewValue() == null) {
          return;
        }
        if (event.getNewValue().getClass().isArray()) {
          final String[] pks = (String[]) event.getNewValue();
          final boolean isMultSelect = pks != null && pks.length > 1;
          IDName[] idNameArr = null;
          if (isMultSelect) {
            final String[] names =
                ((UIRefPane) event.getSource()).getRefNames();
            final String[] codes =
                ((UIRefPane) event.getSource()).getRefCodes();
            idNameArr = new IDName[pks.length];
            for (int i = 0; i < idNameArr.length; i++) {
              idNameArr[i] = new IDName(pks[i], codes[i], names[i]);
            }
          }
          final IDName[] idNames = idNameArr;
          SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
              if (isMultSelect) {
                CellsModel oldCellsModel = table.getDataModel();
                CellPosition anchorCell =
                    oldCellsModel.getSelectModel().getAnchorCell();
                ExtendAreaCell exCell =
                    getDynAreaCell(oldCellsModel, anchorCell);
                IContext context = StateUtil.getContext(table);

                table.getCellEditor(anchorCell).stopCellEditing();

                boolean oldEnableEvent = oldCellsModel.isEnableEvent();
                CellsModel cellsModel =
                    DynAreaUtil.addMultDynAreaRow(oldCellsModel, anchorCell,
                        exCell, pks.length - 1, context, idNames);
                // 复制原来的设置，数据权限，冻结分栏，样式。
                cellsModel.getTableSetting().setCellsAuth(
                    oldCellsModel.getTableSetting().getCellsAuth());
                cellsModel.getTableSetting().setSeperateLockSet(
                    oldCellsModel.getTableSetting().getSeperateLockSet());
                cellsModel.getTableSetting().setStyleSet(
                    oldCellsModel.getTableSetting().getStyleSet());

                // AbsBaseRepDataEditor edit = (AbsBaseRepDataEditor)
                // SwingUtilities.getAncestorOfClass(AbsBaseRepDataEditor.class,
                // table);
                IRepDataEditor repdataEditor =
                    (IRepDataEditor) SwingUtilities.getAncestorOfClass(
                        IRepDataEditor.class, table);
                if (repdataEditor != null) {
                  repdataEditor.setCellsModel(cellsModel);
                  // wangqi 20130621 在setCellsModel方法中会设为false
                  repdataEditor.getCellsModel().setDirty(true);
                }
                else {
                  ReportDataPreviewDesigner designer =
                      (ReportDataPreviewDesigner) SwingUtilities
                          .getAncestorOfClass(ReportDataPreviewDesigner.class,
                              table);
                  designer.setCellsModel(cellsModel);
                  // wangqi 20130621 在setCellsModel方法中会设为false
                  designer.getCellsModel().setDirty(true);
                }
                // if(edit != null)
                // edit.setCellsModel(cellsModel);
                // else{
                // ReportDataPreviewDesigner designer =
                // (ReportDataPreviewDesigner)
                // SwingUtilities.getAncestorOfClass(AbsBaseRepDataEditor.class,
                // table);
                // designer.setCellsModel(cellsModel);
                // }
                // 先禁用事件，避免界面的渲染问题，最终才设置为原来的模型的事件状态。
                try {
                  cellsModel.setEnableEvent(false);
                  cellsModel.getSelectModel().setAnchorCell(anchorCell);
                }
                finally {
                  cellsModel.setEnableEvent(oldEnableEvent);
                }
              }
            }
          });
        }
        else {

        }

      }

      protected ExtendAreaCell getDynAreaCell(CellsModel cellsModel,
          CellPosition pos) {
        DynamicAreaModel dynModel = DynamicAreaModel.getInstance(cellsModel);
        ExtendAreaCell[] dynCells = dynModel.getDynAreaCells();
        for (ExtendAreaCell dynCell : dynCells) {
          AreaPosition area = dynCell.getArea();
          if (area.contain(pos)) {
            return dynCell;
          }
        }
        return null;
      }
    });
    refPane.setMultiSelectedEnabled(true);
    return keyEditor;
  }

  @Override
  public boolean stopCellEditing() {
    return super.stopCellEditing();
  }

  /*
   * tianchuan 20130613
   * 向参照编辑器中设置筛选条件
   */
  private void setFilterCondToRefEditor(final CellsPane table, int row,
      int col, UIRefPane refPane, Context context) {
    // 纳税申报修改
    Object report_pk = context.getAttribute("key_report_pk");
    // 跨组织数据准备报表id
    if ("1001Z810000000007T2P".equals(report_pk)) {
      nc.ui.bd.ref.AbstractRefModel model = refPane.getRefModel();
      if (model != null) {
        if (model instanceof DIRepItemRefModel) {
          ((DIRepItemRefModel) model).setRepItemSysPk("1001Z810000000007T2C");
        }

      }

    }

    // tianchuan 2013.6.13 处理关键字筛选条件
    CellPosition cellPos = CellPosition.getInstance(row, col);
    KeyFmt fmt = DynAreaUtil.getKeyFmt(cellPos, table.getDataModel());
    CellsModel formatModel =
        DynAreaUtil.getDataModelWithExModel(table.getDataModel());
    if (formatModel == null) {
      formatModel = table.getDataModel();
    }
    // 格式态的CellsModel才包含有效的关键字模型
    KeywordModel keywordModel = KeywordModel.getInstance(formatModel);
    KeyFilterParsedContent filterContent =
        keywordModel.getKeyFilterContent(fmt.getKeyPK());
    if (filterContent != null && fmt.getRefCodePK() != null) { // 得到筛选内容
      FormulaModel fmlModel = FormulaModel.getInstance(table.getDataModel());
      UfoFmlExecutor executor = fmlModel.getUfoFmlExecutor();
      // 2013.6.20 保存后，导致引用的CellsModel不同了，这时也要重新生成公式执行器
      if (executor == null || executor.getDataModel() != table.getDataModel()) {
        executor =
            UfoFormulaTraceBizHelper.getFormulaHandler(context,
                table.getDataModel());
        fmlModel.setUfoFmlExecutor(executor);
      }
      try {
        DynamicAreaModel dynAreaModel =
            DynamicAreaModel.getInstance(table.getDataModel());
        // ReportDynCalcEnv dynCalcEnv = executor.getCalcEnv();
        ExtendAreaCell dynAreaCell =
            dynAreaModel.getExtendAreaCellByPos(cellPos);
        AreaPosition groupArea =
            DynAreaUtil.getFormatGroupArea(dynAreaCell, table.getDataModel());
        int stepRow = dynAreaCell.isRowDirection() ? groupArea.getHeigth() : 0;
        int stepCol = dynAreaCell.isRowDirection() ? 0 : groupArea.getWidth();
        int unitAreaNum =
            DynAreaUtil.getOwnerUnitAreaNum(cellPos, dynAreaCell,
                table.getDataModel());
        // 设置分组计算环境参数
        KeyFilterCondParser.setDynAreaCalcEnv(executor, dynAreaCell, stepRow,
            stepCol, unitAreaNum);
        // 根据当前的环境，生成具体要执行的筛选SQL
        String condSql =
            KeyFilterCondParser.parseToExeSql(
                filterContent.getKeyFilterCondObjs(), executor);
        // 为参照设置过滤条件语句
        refPane.getRefModel().addWherePart(condSql);
      }
      finally {
        KeyFilterCondParser.clearDynAreaCalcEnv(executor);
      }
    }
  }

  /*	@Override
  	public Object getCellEditorValue() {
  		Component comp=m_inputEditor.getComponent();
  		if (comp instanceof UIRefPane){
  			((UIRefPane)comp).stopEditing();
  		}
  		
  		String strValue=m_inputEditor.getValue();
  		if (m_inputEditor.isReturValIDName()){
  			UIRefPane refPane=(UIRefPane)m_inputEditor.getComponent();
  			String pk = refPane.getRefPK();
  			String name = null;
  			if(m_inputEditor instanceof OrgInputEditor){
  				name = OrgUtils.getOrgNameWithDept(pk);
  			}else{
  				name = refPane.getRefName();
  			}
  			return new IDName(pk,refPane.getRefCode(), name);
  		}else
  			return strValue;
  	}*/
}
