/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2011 Aimluck,Inc.
 * http://www.aipo.com
 *
 * 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.List;
import java.util.jar.Attributes;

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.eip.account.util.AccountUtils;
import com.aimluck.eip.cayenne.om.account.AvzMPositionPosition;
import com.aimluck.eip.cayenne.om.account.EipMPost;
import com.aimluck.eip.common.ALAbstractSelectData;
import com.aimluck.eip.common.ALDBErrorException;
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.Database;
import com.aimluck.eip.orm.query.ResultList;
import com.aimluck.eip.orm.query.SelectQuery;
import com.aimluck.eip.util.ALEipUtils;

/**
 * 部署の検索データを管理するためのクラスです。 <br />
 */
public class AccountPostSelectData extends
    ALAbstractSelectData<EipMPost, EipMPost> {

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

  // add start
  /** 所属者リスト */
  public List<ALEipUser> memberList = new ArrayList<ALEipUser>(0);

  // add end

  /**
   * 初期処理
   * 
   * @param action
   *            アクションクラス
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @throws ALPageNotFoundException
   * @throws ALDBErrorException
   */
  @Override
  public void init(ALAction action, RunData rundata, Context context)
      throws ALPageNotFoundException, ALDBErrorException {
    String sort = ALEipUtils.getTemp(rundata, context, LIST_SORT_STR);
    if (sort == null || sort.equals("")) {
      ALEipUtils.setTemp(rundata, context, LIST_SORT_STR, ALEipUtils
        .getPortlet(rundata, context)
        .getPortletConfig()
        .getInitParameter("p1a-sort"));
    }

    super.init(action, rundata, context);
  }

  /**
   * 一覧データを取得します。
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @return 部署情報リスト
   */
  @Override
  protected ResultList<EipMPost> selectList(RunData rundata, Context context) {
    try {
      SelectQuery<EipMPost> query = getSelectQuery(rundata, context);
      buildSelectQueryForListView(query);
      buildSelectQueryForListViewSort(query, rundata, context);
      return query.getResultList();
    } catch (Exception ex) {
      logger.error("部署情報の一覧取得に失敗しました。", ex);
      return null;
    }
  }

  /**
   * 検索条件を設定した SelectQuery を返します。 <BR>
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @return SQLオブジェクト
   */
  private SelectQuery<EipMPost> getSelectQuery(RunData rundata, Context context) {
    return Database.query(EipMPost.class);
  }

  /**
   * 詳細データを取得します。 <BR>
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @return DBから取得した部署情報
   * @throws ALPageNotFoundException
   * @throws Exception
   */
  @Override
  protected EipMPost selectDetail(RunData rundata, Context context)
      throws ALPageNotFoundException {
    // change start
    // return AccountUtils.getEipMPost(rundata, context);
    try {
      EipMPost post = AccountUtils.getEipMPost(rundata, context);
      memberList = ALEipUtils.getUsers(post.getGroupName());
      return post;
    } catch (Exception e) {
      logger.error("部署情報の詳細取得に失敗しました。", e);
      throw new ALPageNotFoundException();
    }
    // change end
  }

  /**
   * ResultData に値を格納して返します。（一覧データ） <BR>
   * 
   * @param obj
   *            DBから取得した部署情報
   * @return 画面表示用データ
   */
  @Override
  protected Object getResultData(EipMPost record) {
    AccountPostResultData rd = new AccountPostResultData();
    rd.initField();
    rd.setPostId(record.getPostId().intValue());
    rd.setPostName(record.getPostName());
    // add start
    rd.setParentPostId(record.getParentPostId());
    // add end
    return rd;
  }

  /**
   * ResultData に値を格納して返します。（詳細データ） <BR>
   * 
   * @param obj
   *            DBから取得した部署情報
   * @return 画面表示用部署情報
   */
  @Override
  protected Object getResultDataDetail(EipMPost record) {
    AccountPostResultData rd = new AccountPostResultData();
    rd.initField();
    rd.setPostId(record.getPostId().intValue());
    rd.setPostName(record.getPostName());
    rd.setZipcode(record.getZipcode());
    rd.setAddress(record.getAddress());
    rd.setOutTelephone(record.getOutTelephone());
    rd.setInTelephone(record.getInTelephone());
    rd.setFaxNumber(record.getFaxNumber());
    rd.setGroupName(record.getGroupName());
    // add start
    rd.setParentPostId(record.getParentPostId());
    rd.setParentPostName(ALEipUtils.getPostName(record.getParentPostId()));
    // add end
    return rd;
  }

  /**
   * ソート項目マップ作成
   * 
   * @return ソート項目マップ
   */
  @Override
  protected Attributes getColumnMap() {
    Attributes map = new Attributes();
    // change by motegi start
    // map.putValue("post_name", EipMPost.POST_NAME_PROPERTY);
    map.putValue("post_name", EipMPost.AVZ_MPOST_POSITION_ARRAY_PROPERTY
      + "."
      + AvzMPositionPosition.POSITION_PROPERTY);
    return map;
  }

  /**
   * 
   * @param postid
   * @return
   */
  public List<ALEipUser> getMemberList(long postid) {
    return ALEipUtils.getUsersFromPost((int) postid);
  }

  // add start
  /**
   * あるグループに所属するメンバーのリストを取得します
   * 
   * @param postid
   * @return
   */
  public List<ALEipUser> getMemberListByGroup() {
    return memberList;
  }

  // add end

  // add start

  /**
   * 画面表示用の部署情報リストを取得する （部署１、部署２、部署２、部署１、部署２・・・・・となっている）
   * 
   * @return 部署情報リスト
   */
  public List<AccountPostResultData> getAccountPostHierarchyDataList() {
    List<Object> srcList = getList();
    List<AccountPostResultData> dstList =
      new ArrayList<AccountPostResultData>();

    int depth = 0;
    for (int i = 0; i < srcList.size(); i++) {
      AccountPostResultData rd = (AccountPostResultData) srcList.get(i);
      if (rd.getParentPostId().getValue() == 0) {
        rd.setDepth(depth);
        dstList.add(rd);

        getChildren(rd, srcList, dstList, depth);

      }
    }

    return dstList;
  }

  /**
   * 指定された部署（parent）配下の部署をリストに設定する。
   * 
   * @param parent
   *            部署１
   * @param srcList
   *            設定元リスト
   * @param dstList
   *            設定先リスト
   * @param depth
   *            階層
   */
  private void getChildren(AccountPostResultData parent, List<Object> srcList,
      List<AccountPostResultData> dstList, int depth) {

    depth++;
    for (int i = 0; i < srcList.size(); i++) {
      AccountPostResultData rd = (AccountPostResultData) srcList.get(i);
      if (rd.getParentPostId().getValue() == parent.getPostId().getValue()) {

        rd.setDepth(depth);
        dstList.add(rd);

        getChildren(rd, srcList, dstList, depth);

      }
    }
  }
  // add end
}
