/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.aimluck.eip.office;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.cayenne.ObjectId;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.office.util.OfficeUtils;
import com.aimluck.eip.cayenne.om.portlet.ImwTOffice;
import com.aimluck.eip.cayenne.om.portlet.ImwTOfficeCalendarMap;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipManager;
import com.aimluck.eip.common.ALEipUser;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.services.datasync.ALDataSyncFactoryService;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 勤務先のフォームデータを管理するクラスです。 <BR>
 * 
 */
public class OfficeFormData extends ALAbstractFormData {

  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService
      .getLogger(OfficeFormData.class.getName());

  private DataContext dataContext;

  /** 勤務先ID */
  private int officeId;

  /** 勤務先名 */
  private ALStringField officeName;

  /** 有効/無効 */
  private ALStringField disabled;

  /** */
  private List officeList;

  /** 所属メンバー */
  private ArrayList memberList;

  /** */
  private boolean is_join_member = true;

  /**
   * 初期化します。
   * 
   * @param action
   * @param rundata
   * @param context
   * @see com.aimluck.eip.common.ALAbstractFormData#init(com.aimluck.eip.modules.actions.common.ALAction,
   *      org.apache.turbine.util.RunData, org.apache.velocity.context.Context)
   */
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    dataContext = DatabaseOrmService.getInstance().getDataContext();

  }

  /**
   * 各フィールドを初期化します。 <BR>
   * 
   * @see com.aimluck.eip.common.ALData#initField()
   */
  public void initField() {

    // 勤務先名
    officeName = new ALStringField();
    officeName.setFieldName("勤務先名");
    officeName.setTrim(true);

    // 有効/無効
    disabled = new ALStringField();
    disabled.setFieldName("有効/無効");

    disabled.setTrim(true);
    if (is_join_member)
      memberList = new ArrayList();

  }

  /**
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#setFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean setFormData(RunData rundata, Context context,
      ArrayList msgList) throws ALPageNotFoundException, ALDBErrorException {
    boolean res = super.setFormData(rundata, context, msgList);
    try {
      if (res) {
        if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
          officeId = Integer.parseInt(ALEipUtils.getTemp(rundata, context,
              ALEipConstants.ENTITY_ID));
        }

        //Del 20110627 小濵 Start ---
//        String[] str = rundata.getParameters().getStrings("member_to");
//        if (str != null && str.length > 0) {
//          SelectQuery query = new SelectQuery(TurbineUser.class);
//          Expression exp = ExpressionFactory.inDbExp(
//              TurbineUser.USER_ID_PK_COLUMN, str);
//          query.setQualifier(exp);
//          memberList.addAll(ALEipUtils.getUsersFromSelectQuery(query));
//        }
        //Del 20110627 小濵 End -----
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
      res = false;
    }

    return res;
  }

  /**
   * 各フィールドに対する制約条件を設定します。 <BR>
   * 
   * @see com.aimluck.eip.common.ALAbstractFormData#setValidator()
   */
  protected void setValidator() {
    officeName.setNotNull(true);
    officeName.limitMaxLength(50);
    
  }

  /**
   * フォームに入力されたデータの妥当性検証を行います。 <BR>
   * 
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#validate(java.util.ArrayList)
   */
  protected boolean validate(ArrayList msgList) {
    ArrayList dummy = new ArrayList();
    officeName.validate(msgList);

    if (officeName.toString().lastIndexOf("/") != -1) {
      msgList.add("勤務先名に『 <span class='em'>/</span> 』を用いることはできません。");
    }

    try {
      SelectQuery query = new SelectQuery(ImwTOffice.class);
      if (ALEipConstants.MODE_INSERT.equals(getMode())) {
        Expression exp = ExpressionFactory.matchExp(
            ImwTOffice.OFFICE_NAME_PROPERTY, officeName.getValue());
        query.setQualifier(exp);
      } else if (ALEipConstants.MODE_UPDATE.equals(getMode())) {
        Expression exp1 = ExpressionFactory.matchExp(
            ImwTOffice.OFFICE_NAME_PROPERTY, officeName.getValue());
        query.setQualifier(exp1);
        Expression exp2 = ExpressionFactory.noMatchDbExp(
            ImwTOffice.OFFICE_ID_PK_COLUMN, Integer.valueOf(officeId));
        query.andQualifier(exp2);
      }

      if (dataContext.performQuery(query).size() != 0) {
        msgList.add("勤務先名『 <span class='em'>" + officeName
            + "</span> 』は既に登録されています。");
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return (msgList.size() == 0);
  }

  /**
   * 『勤務先』を読み込みます。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#loadFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean loadFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      ImwTOffice office = OfficeUtils.getImwTOffice(rundata, context);
      if (office == null) {
        return false;
      }

      // 勤務先名
      officeName.setValue(office.getOfficeName());

      officeId = office.getOfficeId().intValue();

      if (is_join_member) {
    
        memberList.addAll(OfficeUtils.getOfficeUsers(officeName.getValue()));
      }

     
      return true;
    } catch (Exception e) {
      logger.error("Exception", e);
      return false;
    }
     
  }

  /**
   * 『勤務先』を追加します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#insertFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean insertFormData(RunData rundata, Context context,
      ArrayList msgList) {

    try {
      Date now = new Date();

      // 新規オブジェクトモデル
      ImwTOffice imwTOffice = (ImwTOffice) dataContext
          .createAndRegisterNewObject(ImwTOffice.class);
      imwTOffice.setOfficeName(officeName.getValue());

      imwTOffice.setDisabled("F");

      // 作成日
      imwTOffice.setCreateDate(now);
      // 更新日
      imwTOffice.setUpdateDate(now);
      // 作成者ＩＤ
      imwTOffice.setCreateUserId(ALEipUtils.getUserId(rundata));
      // 更新者ＩＤ
      imwTOffice.setUpdateUserId(ALEipUtils.getUserId(rundata));

      //Del 20110627 小濵 Start ---
//      // メンバー登録
//      if (is_join_member) {
//        int size = memberList.size();
//        for (int i = 0; i < size; i++) {
//          insertImwTOfficeCalendarMap(imwTOffice, (ALEipUser) memberList.get(i));
//        }
//      }
      //Del 20110627 小濵 End -----
    
      dataContext.commitChanges();
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  private void insertImwTOfficeCalendarMap(ImwTOffice imwTOffice, ALEipUser user) {
    ImwTOfficeCalendarMap map = (ImwTOfficeCalendarMap) dataContext
        .createAndRegisterNewObject(ImwTOfficeCalendarMap.class);
    int userid = (int) user.getUserId().getValue();
    map.setImwTOffice(imwTOffice);
    map.setUserId(userid);
  }

  private boolean deleteImwTOfficeCalendarMap(RunData rundata, Context context) {
    String officeId = ALEipUtils.getTemp(rundata, context,
        ALEipConstants.ENTITY_ID);
    if (officeId == null || Integer.valueOf(officeId) == null) {
      // IDが空の場合
      logger.debug("[OfficeUserFormData] Empty ID...");
      return false;
    }

    SelectQuery query = new SelectQuery(ImwTOfficeCalendarMap.class);
    Expression exp = ExpressionFactory.matchDbExp(
        ImwTOfficeCalendarMap.IMW_TOFFICE_PROPERTY + "."
            + ImwTOffice.OFFICE_ID_COLUMN, officeId);
    query.setQualifier(exp);
    List maps = dataContext.performQuery(query);

    if (maps == null || maps.size() == 0) {
      return true;
    }

    dataContext.deleteObjects(maps);
    return true;
  }

  /**
   * 『勤務先』を更新します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#updateFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean updateFormData(RunData rundata, Context context,
      ArrayList msgList) {
    
    try {
      // オブジェクトモデルを取得
      ImwTOffice imwTOffice = OfficeUtils.getImwTOffice(rundata, context);
      if (imwTOffice == null) {
        return false;
      }

      imwTOffice.setOfficeName(officeName.getValue());

      Date now = new Date();

      // 更新日
      imwTOffice.setUpdateDate(now);

      // 更新者ＩＤ
      imwTOffice.setUpdateUserId(ALEipUtils.getUserId(rundata));


      //Del 20110627 小濵　Start ---
//      //古いImwTOfficeCalendarMapの削除
//      deleteImwTOfficeCalendarMap(rundata, context);
//
//      int size = memberList.size();
//
//      for (int i = 0; i < size; i++) {
//        insertImwTOfficeCalendarMap(imwTOffice, (ALEipUser) memberList.get(i));
//      }
      //Del 20110627 小濵　End -----
       
      // 勤務先を更新
      dataContext.commitChanges();
    } catch (Exception ex) {
      logger.error("Exception", ex);
      return false;
    }
    return true;
  }

  /**
   * 『勤務先』を無効化します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * 
   */
  public boolean disableFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }
      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService.getInstance().getDataSyncHandler()
          .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      ImwTOffice record = OfficeUtils.getImwTOffice(rundata, context);
      
      if(record == null){
        return false;
      }
      
      List offices = OfficeUtils.getOfficeUsers(record.getOfficeName()); 
      int officesize = offices.size();
      if(officesize > 0){
        msgList.add("部署に所属のユーザーが存在します。");
        return false;
      }
      
      String office_id = ALEipUtils.getTemp(rundata, context,
          ALEipConstants.ENTITY_ID);

      if (office_id == null || "".equals(office_id)) {
        return false;
      }

      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
     
      ObjectId oid_user = new ObjectId("ImwTOffice",
          ImwTOffice.OFFICE_ID_PK_COLUMN, office_id);
      ImwTOffice office = (ImwTOffice) dataContext.refetchObject(oid_user);
      office.setDisabled("N");
      
      office.setUpdateDate(new Date());
      
      office.setUpdateUserId(ALEipUtils.getUserId(rundata));
      
      dataContext.commitChanges();

      return true;
    } catch (Exception e) {
      logger.error("Exception", e);
      return false;
    }

  }

  /**
   * 『勤務先』を有効化します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * 
   */
  public boolean enableFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      if (!doCheckSecurity(rundata, context)) {
        return false;
      }
      // WebAPIのDBへ接続できるか確認
      if (!ALDataSyncFactoryService.getInstance().getDataSyncHandler()
          .checkConnect()) {
        msgList.add("コントロールパネルWebAPIのデータベースの接続に失敗したため、処理は実行されませんでした。");
        return false;
      }
      String office_id = ALEipUtils.getTemp(rundata, context,
          ALEipConstants.ENTITY_ID);

      if (office_id == null || "".equals(office_id)) {
        return false;
      }

      DataContext dataContext = DatabaseOrmService.getInstance()
          .getDataContext();
      ObjectId oid_user = new ObjectId("ImwTOffice",
          ImwTOffice.OFFICE_ID_PK_COLUMN, office_id);
      ImwTOffice office = (ImwTOffice) dataContext.refetchObject(oid_user);
      office.setDisabled("F");
      
      office.setUpdateDate(new Date());
      
      office.setUpdateUserId(ALEipUtils.getUserId(rundata));
      
      dataContext.commitChanges();

      return true;
    } catch (Exception e) {
      logger.error("Exception", e);
      return false;
    }
  }

  /**
   * 『勤務先』を削除します。 <BR>
   * 
   * @param rundata
   * @param context
   * @param msgList
   * @return
   * @see com.aimluck.eip.common.ALAbstractFormData#deleteFormData(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context, java.util.ArrayList)
   */
  protected boolean deleteFormData(RunData rundata, Context context,
      ArrayList msgList) {
    try {
      
      ImwTOffice record = OfficeUtils.getImwTOffice(rundata, context);
      
      if(record == null){
        return false;
      }

      List users = OfficeUtils.getOfficeUsers(record.getOfficeName()); 
      int usersize = users.size();
      if(usersize > 0){
        msgList.add("勤務先に所属のユーザーが存在します。");
        return false;
      }
 
      record.setDisabled("T");
      
      record.setUpdateDate(new Date());
      
      record.setUpdateUserId(ALEipUtils.getUserId(rundata));
      
      dataContext.commitChanges();

      return true;
    } catch (Exception e) {
      logger.error("Exception", e);
      return false;
    }
  }

  /**
   * 勤務先有効/無効フラグを取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getDisabled() {
    return disabled;
  }

  /**
   * 
   * @return
   */
  public Map getPostMap() {
    return ALEipManager.getInstance().getPostMap();
  }

  /**
   * 
   * @return
   */
  public Map getPositionMap() {
    return ALEipManager.getInstance().getPositionMap();
  }

  /**
   * 勤務先名を取得します。 <BR>
   * 
   * @return
   */
  public ALStringField getOfficeName() {
    return officeName;
  }

  /**
   * 勤務先IDを取得します。 <BR>
   * 
   * @return
   */
  public int getOfficeId() {
    return officeId;
  }

  public List getOfficeList() {
    return officeList;
  }

  public ArrayList getMemberList() {
    return memberList;
  }

  /**
   * 
   * @param bool
   */
  public void setJoinMember(boolean bool) {
    is_join_member = bool;
  }

  /**
   * 
   * @return
   */
  public boolean isJoinMember() {
    return is_join_member;
  }

}
