/*
 * 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.addressbook;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
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.commons.utils.ALDateUtil;
import com.aimluck.eip.addressbook.util.AddressBookUtils;
import com.aimluck.eip.cayenne.om.security.TurbineGroup;
import com.aimluck.eip.cayenne.om.security.TurbineUser;
import com.aimluck.eip.cayenne.om.security.TurbineUserGroupRole;
import com.aimluck.eip.common.ALBaseUser;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALEipPosition;
import com.aimluck.eip.common.ALEipPost;
import com.aimluck.eip.common.ALEipRole;
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.query.ResultList;
import com.aimluck.eip.query.ALUserDirectSelectQuery;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.user.beans.UserGroupLiteBean;
import com.aimluck.eip.user.beans.UserGroupPositionLiteBean;
import com.aimluck.eip.user.util.UserUtils;
import com.aimluck.eip.util.ALEipUtils;

/**
 * アドレス帳プルダウン検索用データクラスです。(社内アドレス検索用)
 * 
 */
public class AddressBookCorpFilterdSelectData extends
    AbstractAddressBookFilterdSelectData<TurbineUser, ALBaseUser> {

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

  // add by motegi start
  /** グループによる表示切り替え用変数の識別子（部署１） */
  private final String TARGET_PARENT_GROUP_NAME = "target_parent_group_name";

  /** グループによる表示切り替え用変数の識別子 */
  private final String TARGET_GROUP_NAME = "target_group_name";

  /** 役職による表示切り替え用変数の識別子 */
  private final String TARGET_POSITION_ID = "target_position_id";

  /** 役割による表示切り替え用変数の識別子 */
  private final String TARGET_ROLE_ID = "target_role_id";

  // add end

  /** マイグループリスト */
  // del start
  // private final List<ALEipGroup> myGroupList = null;
  // del end
  // add start
  /** ログインユーザーの所属する部署 */
  private String current_group_name;

  /** ログインユーザーの所属する部署の親部署 */
  private String current_parent_group_name;

  /** 検索条件：役職ID */
  private String position_id;

  /** 検索条件：役割ID */
  private String role_id;

  /** 部署1プルダウンを選択されたかどうか（された：1 されない：null） */
  private boolean isChangePost1;

  /** ログインユーザーID */
  private int loginuserid;

  // 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, "name_kana");
    }

    // add start
    loginuserid = ALEipUtils.getUserId(rundata);
    // add end

    // add by motegi start 部署階層化
    String ajax_search_corp =
      rundata.getRequest().getParameter("ajax_search_corp");

    // セッションの絞込み条件クリア処理（リクエストパラメータのクリアフラグがある場合）
    if (rundata.getParameters().containsKey("clearSession")) {
      clearAddressBookCorpSession(rundata, context);
    }

    String change_post1 = null;
    if (ajax_search_corp == null || "".equals(ajax_search_corp)) {

      // セッションから表示対象情報を取得する。
      current_parent_group_name =
        ALEipUtils.getTemp(rundata, context, TARGET_PARENT_GROUP_NAME);
      current_group_name =
        ALEipUtils.getTemp(rundata, context, TARGET_GROUP_NAME);
      position_id = ALEipUtils.getTemp(rundata, context, TARGET_POSITION_ID);
      role_id = ALEipUtils.getTemp(rundata, context, TARGET_ROLE_ID);
      change_post1 = ALEipUtils.getTemp(rundata, context, "change_post1");
      if (change_post1 == null || "".equals(change_post1)) {
        isChangePost1 = false;
      } else {
        isChangePost1 = true;
      }

      if (current_parent_group_name == null) {
        // 初期表示時
        // ログインユーザーの部署1、部署2を取得
        ALEipUser loginuser = ALEipUtils.getALEipUser(rundata);

        List<UserGroupPositionLiteBean> list =
          UserUtils.getPostPositionBeanList((int) loginuser
            .getUserId()
            .getValue());

        if (list != null && list.size() > 0) {
          UserGroupPositionLiteBean b = list.get(0);
          current_parent_group_name = b.getPost1GroupName();
          current_group_name = b.getPost2GroupName();

          // ALEipUtils.setTemp(
          // rundata,
          // context,
          // LIST_FILTER_TYPE_STR,
          // "corp_group");
        }
      }
    } else {
      // プルダウン選択時
      change_post1 = rundata.getRequest().getParameter("change_post1");
      if (change_post1 == null || "".equals(change_post1)) {
        isChangePost1 = false;
        // 部署1プルダウン以外を選択時
        current_parent_group_name =
          rundata.getRequest().getParameter("parent_group_name");
        current_group_name =
          rundata.getRequest().getParameter("post2_group_name");

        if ("ALL".equals(current_group_name)) {
          // 部署2プルダウンで”すべて”を選択された場合
          isChangePost1 = true;
        }
      } else {
        isChangePost1 = true;
        // 部署1プルダウンを選択時
        current_parent_group_name =
          rundata.getRequest().getParameter("parent_group_name");
        current_group_name = "";
      }

      position_id = rundata.getRequest().getParameter("position_id");
      role_id = rundata.getRequest().getParameter("role_id");
    }

    // セッションに表示対象情報をセット
    ALEipUtils.setTemp(
      rundata,
      context,
      TARGET_PARENT_GROUP_NAME,
      current_parent_group_name);
    ALEipUtils.setTemp(rundata, context, TARGET_GROUP_NAME, current_group_name);
    ALEipUtils.setTemp(rundata, context, TARGET_POSITION_ID, position_id);
    ALEipUtils.setTemp(rundata, context, TARGET_ROLE_ID, role_id);
    ALEipUtils.setTemp(rundata, context, "change_post1", change_post1);
    // add end

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

  // add by motegi 部署階層化対応

  /**
   * 表示対象部署２取得
   * 
   * @return 表示対象部署２グループ名（グループ送信ID）
   * 
   */
  public String getCurrentGroupName() {
    return current_group_name;
  }

  /**
   * 表示対象部署1取得
   * 
   * @return 表示対象部署1グループ名（グループ送信ID）
   * 
   */
  public String getCurrentParentGroupName() {
    return current_parent_group_name;
  }

  /**
   * 表示対象役職ID取得
   * 
   * @return 表示対象役職ID
   * 
   */
  public String getPositionId() {
    return position_id;
  }

  /**
   * 表示対象役割ID取得
   * 
   * @return 表示対象役割ID
   * 
   */
  public String getRoleId() {
    return role_id;
  }

  /**
   * 部署2プルダウン用データ取得処理
   * 
   * @return 部署2リスト
   */
  public List<UserGroupLiteBean> getChildGroupList() {

    if (current_parent_group_name != null
      && current_parent_group_name.length() > 0) {
      return UserUtils.getPost2LiteBeans(
        current_parent_group_name,
        true,
        true,
        true);
    }
    return new ArrayList<UserGroupLiteBean>(0);
  }

  // add end

  /**
   * 
   * @param rundata
   * @param context
   */
  public void loadMygroupList(RunData rundata, Context context) {
    // del start
    // try {
    // // マイグループリストの作成
    // List<ALEipGroup> myGroups = ALEipUtils.getMyGroups(rundata);
    // myGroupList = new ArrayList<ALEipGroup>();
    // int length = myGroups.size();
    // for (int i = 0; i < length; i++) {
    // myGroupList.add(myGroups.get(i));
    // }
    // } catch (Exception ex) {
    // logger.error("Exception", ex);
    // }
    // del end
  }

  /**
   * アドレス情報の一覧を取得する。
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @return 社内アドレスリスト
   */
  @Override
  protected ResultList<TurbineUser> selectList(RunData rundata, Context context) {

    try {

      // add start
      if (current_group_name == null
        || (ALEipUtils.GROUPSEND_WITHOUT_POST.equals(current_parent_group_name) && ""
          .equals(current_group_name))) {
        // 部署が指定されていない、もしくは部署1で"グループ送信"を選択した場合は検索しない。
        return new ResultList<TurbineUser>();
      }
      // add end

      // change start
      // SelectQuery<TurbineUser> query = getSelectQuery(rundata, context);
      // buildSelectQueryForListView(query);
      // buildSelectQueryForListViewSort(query, rundata, context);

      ALUserDirectSelectQuery query = new ALUserDirectSelectQuery();
      if (isChangePost1) {
        List<String> tmpList =
          ALEipUtils.getGroupNameList(current_parent_group_name, true);
        query.setGroupNames(tmpList);
      } else {
        if (ALEipUtils.GROUPSEND_WITHOUT_POST.equals(current_parent_group_name)) {
          query.setGroupSendId(current_group_name);
        } else {
          if ("ALL".equals(current_group_name)) {
            List<String> tmpList =
              ALEipUtils.getGroupNameList(current_parent_group_name, true);
            query.setGroupNames(tmpList);
          } else {
            query.setGroupName(current_group_name);
          }
        }
      }

      if (position_id != null && !"".equals(position_id)) {
        query.setPositionId(position_id);
      }

      if (role_id != null && !"".equals(role_id)) {
        query.setRoleId(role_id);
      }

      buildSelectQueryForListView(query);
      // change end

      return query.getResultList();
    } catch (Exception ex) {
      // change start
      // logger.error("Exception", ex);
      String msg =
        "社内アドレスの一覧取得に失敗しました。[" + ALEipUtils.getUserLoginName(loginuserid) + "]";
      logger.error(msg, ex);
      // change end
      return null;
    }
  }

  // add start by motegi
  /**
   * SQLオブジェクトにページング情報を設定する。
   * 
   * @param query
   *            SQLオブジェクト
   */
  protected void buildSelectQueryForListView(ALUserDirectSelectQuery query) {
    query.limit(getRowsNum());
    query.page(current_page);
  }

  // add end

  /**
   * 詳細データを取得します。 <BR>
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @return JetSpeedから取得した社内アドレス情報
   * @throws ALPageNotFoundException
   * @see com.aimluck.eip.common.ALAbstractSelectData#selectDetail(org.apache.turbine.util.RunData,
   *      org.apache.velocity.context.Context)
   */
  @Override
  protected ALBaseUser selectDetail(RunData rundata, Context context)
      throws ALPageNotFoundException {
    try {
      // 指定された ユーザIDを取得
      String userId =
        ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);
      if (userId == null || Integer.valueOf(userId) == null) {
        return null;
      }

      return ALEipUtils.getBaseUser(Integer.valueOf(userId).intValue());
    } catch (Exception ex) {
      // change start
      // logger.error("Exception", ex);
      String msg =
        "社内アドレスの詳細取得に失敗しました。[" + ALEipUtils.getUserLoginName(loginuserid) + "]";
      logger.error(msg, ex);
      // change end
      return null;
    }
  }

  /**
   * ResultData に値を格納して返します。（一覧データ） <BR>
   * 
   * @param obj
   *            DBから取得し社内アドレス情報
   * @return 画面表示用データ
   * @see com.aimluck.eip.common.ALAbstractSelectData#getListData(java.lang.Object)
   */
  @Override
  protected Object getResultData(TurbineUser record) {
    try {
      // add start
      record = ALEipUtils.getTurbineUser(record.getUserId());
      // add end
      return AddressBookUtils.getCorpResultData(record, getStrLength());
    } catch (Exception ex) {
      // change start
      // logger.error("Exception", ex);
      String msg =
        "社内アドレスの一覧取得に失敗しました。[" + ALEipUtils.getUserLoginName(loginuserid) + "]";
      logger.error(msg, ex);
      // change end
      return null;
    }
  }

  /**
   * 詳細情報の返却データ取得。
   * 
   * @param obj
   *            ユーザー情報
   * @return 画面表示用データ
   */
  @Override
  protected Object getResultDataDetail(ALBaseUser record) {
    try {
      AddressBookResultData rd = new AddressBookResultData();
      rd.initField();
      // アドレスID の設定
      int userId = Integer.valueOf(record.getUserId()).intValue();
      rd.setAddressId(userId);
      rd.setName(new StringBuffer()
        .append(record.getLastName())
        .append(' ')
        .append(record.getFirstName())
        .toString());
      rd.setNameKana(new StringBuffer()
        .append(record.getLastNameKana())
        .append(' ')
        .append(record.getFirstNameKana())
        .toString());
      rd.setEmail(record.getEmail());
      rd.setTelephone(record.getOutTelephone());
      rd.setInTelephone(record.getInTelephone());
      rd.setCellularPhone(record.getCellularPhone());
      rd.setCellularMail(record.getCellularMail());

      // mod by motegi start 部署階層化対応
      // rd.setPostList(AddressBookUtils.getPostBeanList(userId));
      rd.setPostList(UserUtils.getPostPositionBeanList(userId));
      // mod end
      // del by motegi start 部署階層化対応
      // if (record.getPositionId() > 0) {
      // rd.setPositionName(ALCommonUtils.compressString(ALEipUtils
      // .getPositionName(record.getPositionId()), getStrLength()));
      // }
      // del end

      rd.setCreateDate(ALDateUtil.format(record.getCreated(), "yyyy年M月d日"));
      rd.setUpdateDate(ALDateUtil.format(record.getModified(), "yyyy年M月d日"));

      /** 従業員コード追加対応 add by motegi */
      rd.setLoginName(record.getUserName());

      // add by motegi start 部署階層化対応
      rd.setRoleList(UserUtils.getRoleBeanList(userId));
      // add end

      // add start
      // メールアドレスはWebメールアカウントを表示
      rd
        .setMailAccountList(UserUtils.getUserWebmailAccountLiteBeanList(userId));
      // add end

      return rd;
    } catch (Exception ex) {
      // change start
      // logger.error("Exception", ex);
      String msg =
        "社内アドレスの詳細取得に失敗しました。[" + ALEipUtils.getUserLoginName(loginuserid) + "]";
      logger.error(msg, ex);
      // change end
      return null;
    }
  }

  /**
   * ソート用カラムマップ取得
   * 
   * @return ソート用カラムマップ
   */
  @Override
  protected Attributes getColumnMap() {
    Attributes map = new Attributes();
    map.putValue("corp_group", TurbineUser.TURBINE_USER_GROUP_ROLE_PROPERTY
      + "."
      + TurbineUserGroupRole.TURBINE_GROUP_PROPERTY
      + "."
      + TurbineGroup.GROUP_NAME_COLUMN);
    map.putValue("name_kana", TurbineUser.LAST_NAME_KANA_PROPERTY);
    return map;
  }

  // del start
  // /**
  // * 検索条件を設定した SelectQuery を返します。
  // *
  // * @param rundata
  // * @param context
  // * @return
  // */
  // private SelectQuery<TurbineUser> getSelectQuery(RunData rundata,
  // Context context) {
  // SelectQuery<TurbineUser> query = Database.query(TurbineUser.class);
  //
  // Expression exp11 =
  // ExpressionFactory.matchExp(TurbineUser.DISABLED_PROPERTY, "F");
  // query.setQualifier(exp11);
  // Expression exp21 =
  // ExpressionFactory.noMatchDbExp(TurbineUser.USER_ID_PK_COLUMN, Integer
  // .valueOf(1));
  // Expression exp22 =
  // ExpressionFactory.noMatchDbExp(TurbineUser.USER_ID_PK_COLUMN, Integer
  // .valueOf(2));
  // Expression exp23 =
  // ExpressionFactory.noMatchDbExp(TurbineUser.USER_ID_PK_COLUMN, Integer
  // .valueOf(3));
  // query.andQualifier(exp21.andExp(exp22).andExp(exp23));
  //
  // return getSelectQueryForIndex(query, rundata, context);
  // }
  // del end

  /**
   * インデックス検索のためのカラムを返します。
   * 
   * @return
   */
  @Override
  protected String getColumnForIndex() {
    return TurbineUser.LAST_NAME_KANA_PROPERTY;
  }

  /**
   * 部署１リスト取得
   * 
   * @return 部署１リスト
   */
  // public Map<Integer, ALEipPost> getPostMap() {
  public List<ALEipPost> getPostMap() {

    // mod by motegi start 部署階層化対応
    // return ALEipManager.getInstance().getPostMap();
    // return ALEipUtils.getPostMap();
    List<ALEipPost> list = ALEipUtils.getPostMap(false, false);
    ALEipPost al = new ALEipPost();
    al.initField();
    al.setGroupName(ALEipUtils.GROUPSEND_WITHOUT_POST);
    al.setPostName("役職・役割で絞り込み");
    list.add(0, al);
    return list;
    // mod end
  }

  /**
   * 
   * @return
   */
  // del start
  // public List<ALEipGroup> getMyGroupList() {
  // return myGroupList;
  // }
  // del end
  /**
   * アクセス権限チェック用メソッド。 cを返します。
   * 
   * @return Map<Integer, ALEipRole>
   */
  @Override
  public String getAclPortletFeature() {
    return ALAccessControlConstants.POERTLET_FEATURE_ADDRESSBOOK_ADDRESS_INSIDE;
  }

  // add by motegi start 部署階層化対応
  /**
   * 役職一覧を取得します。
   * 
   * @return 役職一覧
   */
  public Map<Integer, ALEipPosition> getPositionMap() {
    return ALEipUtils.getPositionMap();
  }

  /**
   * 役割一覧を取得します。
   * 
   * @return 役割一覧
   */
  public Map<Integer, ALEipRole> getRoleMap() {
    return ALEipUtils.getRoleMap();
  }

  /**
   * 絞込み条件をクリア
   * 
   * @param rundata
   * @param context
   */
  public void clearAddressBookCorpSession(RunData rundata, Context context) {
    ALEipUtils.removeTemp(rundata, context, TARGET_PARENT_GROUP_NAME);
    ALEipUtils.removeTemp(rundata, context, TARGET_GROUP_NAME);
    ALEipUtils.removeTemp(rundata, context, TARGET_POSITION_ID);
    ALEipUtils.removeTemp(rundata, context, TARGET_ROLE_ID);
    ALEipUtils.removeTemp(rundata, context, "change_post1");
  }
  // add end

}
