/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * Copyright(C) 2011 avanza Co.,Ltd. All rights reserved.
 * http://www.avnz.co.jp/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.aimluck.eip.account;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
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.cayenne.om.account.AvzMPositionPosition;
import com.aimluck.eip.cayenne.om.account.AvzMPostPosition;
import com.aimluck.eip.cayenne.om.account.EipMPost;
import com.aimluck.eip.common.ALAbstractFormData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipManager;
import com.aimluck.eip.common.ALEipPost;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.modules.actions.common.ALAction;
import com.aimluck.eip.orm.Database;
import com.aimluck.eip.orm.query.ResultList;
import com.aimluck.eip.orm.query.SelectQuery;

/**
 * 部署の順番情報のフォームデータを管理するためのクラスです。 <br />
 */
public class AccountPostChangeTurnFormData extends ALAbstractFormData {

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

  /** 部署情報のIDのリスト(カンマ区切り) */
  private ALStringField positions;

  /** 部署情報のIDのリスト */
  private String[] positionIds;

  /** 部署情報のリスト */
  private List<ALEipPost> positionList = null;

  /**
   * 初期化します。
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    super.init(action, rundata, context);

    positionList = new ArrayList<ALEipPost>();
  }

  /**
   * 各フィールドを初期化します。
   */
  public void initField() {
    // ユーザ名のリスト
    positions = new ALStringField();
    positions.setFieldName("部署リスト");
    positions.setTrim(true);
  }

  /**
   * フォームデータ処理
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @param msgList
   *            エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   */
  @Override
  protected boolean setFormData(RunData rundata, Context context,
      List<String> msgList) throws ALPageNotFoundException, ALDBErrorException {
    boolean res = true;
    try {
      res = super.setFormData(rundata, context, msgList);
      if (res) {
        if (positions.getValue() == null || positions.getValue().equals("")) {

          // 先ず部署１を取得する。
          SelectQuery<EipMPost> query = Database.query(EipMPost.class);
          Expression exp =
            ExpressionFactory.matchExp(EipMPost.PARENT_POST_ID_PROPERTY, 0);
          query.setQualifier(exp);
          query.orderAscending(EipMPost.AVZ_MPOST_POSITION_ARRAY_PROPERTY
            + "."
            + AvzMPostPosition.POSITION_PROPERTY);

          ResultList<EipMPost> tmpPost1List = query.getResultList();
          for (EipMPost p1 : tmpPost1List) {

            // 取得した部署1
            ALEipPost d1 = new ALEipPost();
            d1.initField();
            d1.setPostId(p1.getPostId());
            d1.setPostName(p1.getPostName());
            d1.setParentPostId(p1.getParentPostId());
            positionList.add(d1);

            SelectQuery<EipMPost> queryPost2 = Database.query(EipMPost.class);
            Expression exp2 =
              ExpressionFactory.matchExp(EipMPost.PARENT_POST_ID_PROPERTY, p1
                .getPostId());
            queryPost2.setQualifier(exp2);
            queryPost2
              .orderAscending(EipMPost.AVZ_MPOST_POSITION_ARRAY_PROPERTY
                + "."
                + AvzMPostPosition.POSITION_PROPERTY);
            ResultList<EipMPost> tmpPost2List = queryPost2.getResultList();

            // 取得した部署2
            for (EipMPost p2 : tmpPost2List) {
              ALEipPost d = new ALEipPost();
              d.initField();
              d.setPostId(p2.getPostId());
              d.setPostName("- " + p2.getPostName());
              d.setParentPostId(p2.getParentPostId());
              positionList.add(d);
            }
          }

        } else {
          StringTokenizer st = new StringTokenizer(positions.getValue(), ",");
          positionIds = new String[st.countTokens()];
          int count = 0;
          while (st.hasMoreTokens()) {
            positionIds[count] = st.nextToken();
            count++;
          }
        }
      }
    } catch (Exception ex) {
      String msg = "部署情報順番設定画面の表示に失敗しました。";
      logger.error(msg, ex);
      throw new ALDBErrorException();
    }
    return res;
  }

  /**
   * ※未使用
   */
  @Override
  protected void setValidator() {
  }

  /**
   * ※未使用
   */
  @Override
  protected boolean validate(List<String> msgList) {
    return (msgList.size() == 0);
  }

  /**
   * ※未使用
   */
  @Override
  protected boolean loadFormData(RunData rundata, Context context,
      List<String> msgList) {
    return false;
  }

  /**
   * ※未使用
   */
  @Override
  protected boolean insertFormData(RunData rundata, Context context,
      List<String> msgList) {
    return false;
  }

  /**
   * 部署表示順番を更新します。
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @param msgList
   *            エラーメッセージリスト
   * @return 処理結果(正常：true、異常:false)
   */
  @Override
  protected boolean updateFormData(RunData rundata, Context context,
      List<String> msgList) {
    boolean res = true;
    try {
      Expression exp1 =
        ExpressionFactory.inDbExp(EipMPost.POST_ID_PK_COLUMN, positionIds);
      SelectQuery<EipMPost> query = Database.query(EipMPost.class, exp1);
      query.orderAscending(EipMPost.AVZ_MPOST_POSITION_ARRAY_PROPERTY
        + "."
        + AvzMPositionPosition.POSITION_PROPERTY);
      List<EipMPost> list = query.fetchList();

      LinkedHashMap<String, EipMPost> loginnameUserMap =
        new LinkedHashMap<String, EipMPost>();
      for (EipMPost user : list) {
        loginnameUserMap.put(user.getPostId().toString(), user);
      }

      int newPosition = 1;
      for (String name : positionIds) {
        EipMPost user = loginnameUserMap.get(name);
        AvzMPostPosition userPosition = user.getAvzMPostPositionArray();
        userPosition.setPosition(newPosition);
        newPosition++;
      }
      Database.commit();
      ALEipManager.getInstance().reloadPost();
    } catch (Exception e) {
      String msg = "部署情報の順番更新に失敗しました。";
      logger.error(msg, e);
      msgList.add(msg);
      Database.rollback();
      return false;
    }
    return res;
  }

  /**
   * ※未使用
   */
  @Override
  protected boolean deleteFormData(RunData rundata, Context context,
      List<String> msgList) {
    return false;
  }

  /**
   * 部署情報のリストを取得する．
   * 
   * @return 部署情報のリスト
   */
  public List<ALEipPost> getPostList() {
    return positionList;
  }

}
