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

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;

import javax.mail.Address;
import javax.mail.Message;
import javax.mail.internet.InternetAddress;

import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.jetspeed.om.security.JetspeedUser;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALNumberField;
import com.aimluck.commons.field.ALStringField;
import com.aimluck.eip.cayenne.om.portlet.AvzTMailSend;
import com.aimluck.eip.cayenne.om.portlet.AvzTMailSendRecvAcl;
import com.aimluck.eip.cayenne.om.portlet.EipMMailAccount;
import com.aimluck.eip.cayenne.om.portlet.EipTMailFolder;
import com.aimluck.eip.common.ALAbstractSelectData;
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.mail.ALFolder;
import com.aimluck.eip.mail.ALLocalMailMessage;
import com.aimluck.eip.mail.ALMailFactoryService;
import com.aimluck.eip.mail.ALMailHandler;
import com.aimluck.eip.mail.ALMailMessage;
import com.aimluck.eip.mail.ALPop3MailReceiveThread;
import com.aimluck.eip.mail.beans.ALMailSearchCondition;
import com.aimluck.eip.mail.util.ALMailUtils;
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.services.storage.ALStorageService;
import com.aimluck.eip.util.ALCommonUtils;
import com.aimluck.eip.util.ALEipUtils;
import com.aimluck.eip.webmail.beans.WebMailFolderVolumeSummaryBean;
import com.aimluck.eip.webmail.beans.WebmailAccountLiteBean;
import com.aimluck.eip.webmail.util.WebMailUtils;
import com.sk_jp.mail.MailUtility;

/**
 * <HR>
 * Web送信メール検索データを管理するためのクラスです。 <br />
 * <p>
 * <HR>
 * <p>
 * 
 */
public class WebMailSendSelectData extends ALAbstractSelectData<AvzTMailSend, ALMailMessage> {
  /** logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(WebMailSendSelectData.class.getName());

  /** 現在選択されているタブ (＝受信メール or 送信メール) */
  private String currentTab;

  JetspeedUser user = null;

  /** ユーザーID */
  private int userId = -1;

  /** アカウントID */
  private int accountId = -1;

  /** フォルダID */
  private int folderId = -1;

  /** フォルダに対する未読メール数のマップ */
  private Map<Integer, Integer> unreadMailSumMap;

  /** 最終受信日 */
  private String finalAccessDateStr;

  private String orgId;

  /** メールフォルダ情報 */
  private ALFolder folder;

  /** メールアカウント一覧 */
  private List<WebmailAccountLiteBean> mailAccountList;

  /** メールフォルダ一覧 */
  // change start 運用保守障害５８
  // private List<WebMailFolderResultData> mailFolderList;
  private List<ExtFolderInfo> mailFolderList;

  // change end

  /** 選択されたフォルダ情報 */
  private ExtFolderInfo selected_folderinfo;

  private List<ExtFolderInfo> folder_hierarchy_list;

  /** ごみ箱フォルダID（初期表示時選択） */
  private int trash_folder_id;

  /** 検索ワード 本文 */
  protected ALStringField searchWord;

  /** 検索ワード 件名 */
  protected ALStringField searchSubjectWord;

  /** 検索ワード 受取人 */
  protected ALStringField searchAddressWord;

  /** 検索 サブフォルダも含む */
  protected ALStringField includeSubFolder;

  /** １ユーザーあたりメールボックス容量上限 */
  private ALNumberField mailBoxVolumeMax;

  /** メールボックス使用容量計 */
  private ALNumberField mailBoxVolumeSummary;

  /** メールボックス使用率 */
  private ALNumberField mailBoxVolumePct;

  /** メールボックス未使用率 */
  private ALNumberField mailBoxVolumeEmptyPct;

  /** メッセージリスト */
  private List<String> msgList;

  /** 下書きフラグ */
  private boolean isDraft;

  /** 代理受信アカウントフラグ */
  private final boolean isRepresent = false;

  /**
   * 初期処理
   * <p>
   * 
   * @param action
   * @param rundata
   * @param context
   * @exception Exception
   *                異常発生時にスローします。
   */
  @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("p2a-sort"));
    }

    orgId = Database.getDomainName();
    userId = ALEipUtils.getUserId(rundata);
    user = (JetspeedUser) ((JetspeedRunData) rundata).getUser();

    // 現在選択されているタブ（受信トレイor送信トレイ）
    String tabParam = rundata.getParameters().getString("tab");
    currentTab = ALEipUtils.getTemp(rundata, context, "tab");
    if (tabParam == null && currentTab == null) {
      ALEipUtils.setTemp(rundata, context, "tab", WebMailUtils.TAB_SENT);
      currentTab = WebMailUtils.TAB_SENT;
    } else if (tabParam != null) {
      ALEipUtils.setTemp(rundata, context, "tab", tabParam);
      currentTab = tabParam;
    }

    // フォルダ種別 送信
    String folder_kind = ALMailUtils.FOLDER_KIND_SEND;

    // 現在処理中のアカウントID
    String tmpAccoundId = ALEipUtils.getTemp(rundata, context, WebMailUtils.ACCOUNT_ID);
    if (tmpAccoundId == null || "".equals(tmpAccoundId)) {
      ALEipUtils
        .setTemp(rundata, context, WebMailUtils.ACCOUNT_ID, ALEipUtils.getPortlet(rundata, context).getPortletConfig().getInitParameter("p3a-accounts"));
    }

    // 自ポートレットからのリクエストであれば、パラメータを展開しセッションに保存する。
    if (ALEipUtils.isMatch(rundata, context)) {
      // アカウントID
      if (rundata.getParameters().containsKey(WebMailUtils.ACCOUNT_ID)) {
        ALEipUtils.setTemp(rundata, context, WebMailUtils.ACCOUNT_ID, rundata.getParameters().getString(WebMailUtils.ACCOUNT_ID));
      }

      // フォルダID
      if (rundata.getParameters().containsKey(WebMailUtils.FOLDER_ID)) {
        ALEipUtils.setTemp(rundata, context, WebMailUtils.FOLDER_ID, rundata.getParameters().getString(WebMailUtils.FOLDER_ID));
      }
    }

    try {
      accountId = Integer.parseInt(ALEipUtils.getTemp(rundata, context, WebMailUtils.ACCOUNT_ID));
    } catch (Exception e) {
      accountId = 0;
    }

    try {
      folderId = Integer.parseInt(ALEipUtils.getTemp(rundata, context, WebMailUtils.FOLDER_ID));
    } catch (Exception e) {
      folderId = 0;
    }

    // アカウントIDが取得できなかったとき、デフォルトのアカウントIDを取得する
    if (accountId == 0) {
      try {
        Expression exp = ExpressionFactory.matchExp(EipMMailAccount.USER_ID_PROPERTY, userId);
        SelectQuery<EipMMailAccount> query = Database.query(EipMMailAccount.class, exp);

        query.select(EipMMailAccount.ACCOUNT_ID_PK_COLUMN);
        List<EipMMailAccount> accounts = query.fetchList();
        if (accounts != null && accounts.size() > 0) {
          EipMMailAccount account = accounts.get(0);
          accountId = account.getAccountId();
          ALEipUtils.setTemp(rundata, context, WebMailUtils.ACCOUNT_ID, Integer.toString(accountId));
        } else {
          // アカウントが一つも見つからなかった
          return;
        }
      } catch (Exception e) {
        // add start
        throw new ALDBErrorException();
        // add end
      }
    }

    // アカウントを取得
    EipMMailAccount account = ALMailUtils.getMailAccount(userId, accountId);

    // 現在選択中のフォルダを取得
    EipTMailFolder mailFolder = WebMailUtils.getEipTMailFolder(account, String.valueOf(folderId));

    // フォルダが取得できなかった場合、
    // またはセッションから取得したフォルダIDが送信トレイのものでない場合は
    // アカウントに紐付いた送信トレイのフォルダIDを取得する
    if (mailFolder == null || !ALMailUtils.FOLDER_KIND_SEND.equals(mailFolder.getFolderKind())) {
      folderId = account.getDefaultSendFolderId();

      // セッションにセット
      ALEipUtils.setTemp(rundata, context, WebMailUtils.FOLDER_ID, String.valueOf(folderId));

      // 再取得
      mailFolder = WebMailUtils.getEipTMailFolder(account, String.valueOf(folderId));
    }
    try {
      // 下書きフォルダの場合、下書きフラグON
      isDraft = (mailFolder.getFolderType().equals(ALMailUtils.FOLDER_TYPE_DRAFT));

      // プルダウン用のフォルダリストを取得
      // change start 2012.2.6 受入障害対応No.261 携帯側「下書きフォルダ」非表示対応
      // mailFolderList = WebMailUtils.getMailFolderAll(account, folder_kind);

      // remove start 運用保守障害５８
      // if (rundata.getParameters().containsKey("isMobile")) {
      // mailFolderList =
      // WebMailUtils.getMailFolderAllForMobile(account, folder_kind);
      // } else {
      // remove end
      // change start 運用保守障害５８
      // mailFolderList = WebMailUtils.getMailFolderAll(account, folder_kind);
      mailFolderList = new ArrayList<ExtFolderInfo>();

      List<ExtFolderInfo> tmp = WebMailUtils.getFolderList(WebMailUtils.ROOT_PARENT_FODLER_ID, accountId, WebMailConsts.SEND_FOLDER);

      mailFolderList.addAll(tmp);

      if (rundata.getParameters().containsKey("isMobile")) {
        // 携帯・スマホの場合は下書きフォルダは除外
        for (int i = 0; i < mailFolderList.size(); i++) {
          if (ALMailUtils.FOLDER_TYPE_DRAFT.equals(mailFolderList.get(i).getFolderType())) {
            mailFolderList.remove(i);
            break;
          }
        }
      }
      // change end 運用保守障害５８

      // remove start 運用保守障害５８
      // }
      // remove end
      // change end 2012.2.6
      // remove start 運用保守障害５８
      // for (int i = 0; i < mailFolderList.size(); i++) {
      // // ルートフォルダは除く
      // if (mailFolderList.get(i).getParentFolderId() == 0) {
      // mailFolderList.remove(i);
      // }
      // }
      // remove end 運用保守障害５８
      for (int i = 0; i < mailFolderList.size(); i++) {
        // 初期選択用ごみ箱フォルダID
        if (ALMailUtils.FOLDER_TYPE_TRASH.equals(mailFolderList.get(i).getFolderType())) {
          trash_folder_id = mailFolderList.get(i).getFolderId();
        }
      }
    } catch (Exception e) {
      throw new ALDBErrorException();
    }

    // ページャからきた場合に検索ワードをセッションへ格納する
    if (!rundata.getParameters().containsKey(ALEipConstants.LIST_START)
      && !rundata.getParameters().containsKey(ALEipConstants.LIST_SORT)
      && rundata.getParameters().containsKey("sword")) {
      ALEipUtils.setTemp(rundata, context, "WebMailWord", rundata.getParameters().getString("sword"));
    }

    if (!rundata.getParameters().containsKey(ALEipConstants.LIST_START)
      && !rundata.getParameters().containsKey(ALEipConstants.LIST_SORT)
      && rundata.getParameters().containsKey("subjectword")) {
      ALEipUtils.setTemp(rundata, context, "WebMailSubjectWord", rundata.getParameters().getString("subjectword"));
    }

    if (!rundata.getParameters().containsKey(ALEipConstants.LIST_START)
      && !rundata.getParameters().containsKey(ALEipConstants.LIST_SORT)
      && rundata.getParameters().containsKey("addressword")) {
      ALEipUtils.setTemp(rundata, context, "WebMailAddressWord", rundata.getParameters().getString("addressword"));
    }

    if (!rundata.getParameters().containsKey(ALEipConstants.LIST_START)
      && !rundata.getParameters().containsKey(ALEipConstants.LIST_SORT)
      && rundata.getParameters().containsKey("includesubfolder")) {
      ALEipUtils.setTemp(rundata, context, "WebMailIncludeSubFolder", rundata.getParameters().getString("includesubfolder"));
    }

    // add start
    String mode = rundata.getParameters().getString("mode");
    if ("condition_clear".equals(mode)) {
      // 検索条件クリア指定があった場合
      ALEipUtils.setTemp(rundata, context, "WebMailWord", "");
      ALEipUtils.setTemp(rundata, context, "WebMailSubjectWord", "");
      ALEipUtils.setTemp(rundata, context, "WebMailAddressWord", "");
      ALEipUtils.setTemp(rundata, context, "WebMailIncludeSubFolder", "");
    }

    // 検索ワードの設定
    searchWord = new ALStringField();
    searchWord.setTrim(true);
    // if ("ajaxsearch".equals(mode)) {
    searchWord.setValue(ALEipUtils.getTemp(rundata, context, "WebMailWord"));
    // }

    searchSubjectWord = new ALStringField();
    searchSubjectWord.setTrim(true);
    // if ("ajaxsearch".equals(mode)) {
    searchSubjectWord.setValue(ALEipUtils.getTemp(rundata, context, "WebMailSubjectWord"));
    // }

    searchAddressWord = new ALStringField();
    searchAddressWord.setTrim(true);
    // if ("ajaxsearch".equals(mode)) {
    searchAddressWord.setValue(ALEipUtils.getTemp(rundata, context, "WebMailAddressWord"));
    // }

    includeSubFolder = new ALStringField();
    includeSubFolder.setTrim(true);
    includeSubFolder.setValue(ALEipUtils.getTemp(rundata, context, "WebMailIncludeSubFolder"));

    // 現在選択しているタブが受信トレイか送信トレイか
    if (accountId > 0) {
      int type_mail = (WebMailUtils.TAB_RECEIVE.equals(currentTab)) ? ALFolder.TYPE_RECEIVE : ALFolder.TYPE_SEND;
      ALMailHandler handler = ALMailFactoryService.getInstance().getMailHandler();

      // 全文検索
      ALMailSearchCondition cond = new ALMailSearchCondition();
      cond.setSearchWord(searchWord.getValue());
      cond.setSearchSubjectWord(searchSubjectWord.getValue());
      cond.setSearchAddressWord(searchAddressWord.getValue());
      cond.setIncludeSubFolder(includeSubFolder.getValue());
      folder = handler.getALFolder(type_mail, orgId, userId, Integer.valueOf(accountId), cond);
      folder.setRowsNum(super.getRowsNum());
    }

    super.init(action, rundata, context);

    // ソート対象が日時だった場合、ソート順を逆にする．
    if ("date".equals(ALEipUtils.getTemp(rundata, context, LIST_SORT_STR))) {
      String sort_type = ALEipUtils.getTemp(rundata, context, LIST_SORT_TYPE_STR);
      if (sort_type == null || sort_type.equals("")) {
        ALEipUtils.setTemp(rundata, context, LIST_SORT_TYPE_STR, ALEipConstants.LIST_SORT_TYPE_DESC);
      }
    }

    // フォルダ階層リスト取得
    folder_hierarchy_list = WebMailUtils.getFolderList(WebMailUtils.ROOT_PARENT_FODLER_ID, accountId, folder_kind);

    // 現在選択されているフォルダ
    if (folder_hierarchy_list != null && folder_hierarchy_list.size() > 0) {
      int size = folder_hierarchy_list.size();
      for (int i = 0; i < size; i++) {
        ExtFolderInfo info = folder_hierarchy_list.get(i);
        if (info.getFolderId() == folderId) {
          selected_folderinfo = info;
          break;
        }
      }
      if (selected_folderinfo == null) {
        selected_folderinfo = folder_hierarchy_list.get(0);
      }
    }

  }

  /**
   * メールアカウント一覧を設定する。
   * <p>
   * 
   * @param rundata
   * @param context
   */
  public void loadMailAccountList(RunData rundata, Context context) {
    try {
      // メールアカウント一覧
      mailAccountList = new ArrayList<WebmailAccountLiteBean>();

      // ログインユーザーの全アカウントを取得
      List<EipMMailAccount> aList = WebMailUtils.getMailAccountNameList(ALEipUtils.getUserId(rundata));

      if (aList == null) {
        return;
      }

      WebmailAccountLiteBean bean = null;
      Iterator<EipMMailAccount> iter = aList.iterator();
      // メールアカウント一覧に取得した全アカウントを設定
      while (iter.hasNext()) {
        EipMMailAccount account = iter.next();
        bean = WebMailUtils.getWebmailAccountLiteBean(account, false);
        mailAccountList.add(bean);
      }
    } catch (Exception ex) {
      logger.error("Exception", ex);
    }
  }

  /**
   * メールボックス容量情報を取得して設定します。
   * <p>
   * 設定内容:<BR>
   * メールボックス容量上限(MB) <BR>
   * メールボックス使用率 <BR>
   * メールボックス未使用率 <BR>
   * メールボックス使用容量計(MB) <BR>
   * 
   * @param rundata
   *            JetSpeedランデータ
   * @param context
   *            JetSpeedコンテキスト
   * @throws Exception
   */
  public void loadMailBoxVolume(RunData rundata, Context context) throws Exception {
    try {

      // ログインユーザーの全アカウントID取得
      List<EipMMailAccount> accountList = WebMailUtils.getMailAccountNameList(ALEipUtils.getUserId(rundata));
      List<Integer> accountIdList = new ArrayList<Integer>();
      for (int i = 0; i < accountList.size(); i++) {
        accountIdList.add(accountList.get(i).getAccountId());
      }
      // メールボックス容量上限取得
      mailBoxVolumeMax = new ALNumberField();
      mailBoxVolumeMax.setValue(WebMailUtils.getMailVolumeMax());

      // ログインユーザーの全フォルダ使用容量計取得
      WebMailFolderVolumeSummaryBean folderVolumeSummaryBean = new WebMailFolderVolumeSummaryBean();

      folderVolumeSummaryBean = WebMailUtils.getFolderVolumeSummaryBean(accountIdList);
      // メールボックス使用率
      mailBoxVolumePct = new ALNumberField();
      mailBoxVolumePct = folderVolumeSummaryBean.getMailBoxVolumePct();
      // メールボックス未使用率
      mailBoxVolumeEmptyPct = new ALNumberField();
      mailBoxVolumeEmptyPct = folderVolumeSummaryBean.getMailBoxVolumeEmptyPct();
      // フォルダ使用容量計
      mailBoxVolumeSummary = new ALNumberField();
      mailBoxVolumeSummary = folderVolumeSummaryBean.getFolderVolumeSummary();

      // メールボックス使用率が100%以上の場合
      msgList = new ArrayList<String>();
      // change start 受入障害対応No.218
      // if (Integer.parseInt(mailBoxVolumePct.toString()) >= 100) {
      if (Long.parseLong(mailBoxVolumePct.toString()) >= 100) {
        // change end
        msgList.add("メールボックスがいっぱいの為メール送信が行えません。下の「メール退避・削除・移動」より退避、削除を行ってください。 ");
      }

    } catch (Exception ex) {
      throw ex;
    }

  }

  /**
   * メールの一覧を取得する。<BR>
   * 
   * @param rundata
   * @param context
   * @return ResultList<AvzTMailSend> 送信メール一覧情報
   */
  @Override
  protected ResultList<AvzTMailSend> selectList(RunData rundata, Context context) {
    try {
      if (folder == null) {
        return null;
      }

      WebMailUtils.setFolderVisible(folder_hierarchy_list, selected_folderinfo);

      // フォルダごとの未読メール数を取得
      // ・フォルダの切り替え、受信送信タブの移動、ソート時には未読メール数をセッションから取得する
      // ・メールのフォルダ間移動、メール詳細画面を出した後は未読メール数をデータベースから取得する
      // ・セッションが空の場合は未読メール数をデータベースから取得する
      String unreadMailSumMapString = ALEipUtils.getTemp(rundata, context, "unreadsendmailsummap");
      if ((rundata.getParameters().containsKey("noupdateunread") || rundata.getParameters().containsKey("sort") || rundata.getParameters().containsKey("tab"))
        && unreadMailSumMapString != null
        && !rundata.getParameters().containsKey("updateunread")) {
        // セッションから得た文字列をHashMapに再構成
        unreadMailSumMap = WebMailUtils.getUnreadMailSumMapFromString(unreadMailSumMapString);
      } else {
        // セッションが空か、パラメータが指定されていなければ取得しなおす
        unreadMailSumMap = WebMailUtils.getUnreadMailNumberMap(rundata, userId, accountId);
      }

      // セッションに保存
      ALEipUtils.setTemp(rundata, context, "unreadsendmailsummap", unreadMailSumMap.toString());

      return folder.getIndexRowsSend(rundata, context);
    } catch (Exception ex) {
      logger.error("送信メール一覧取得に失敗しました。　" + ALEipUtils.getUserFullName(userId), ex);
      return null;
    }
  }

  /**
   * メールの詳細を取得する。<BR>
   * 
   * @param rundata
   * @param context
   * @return
   * @throws ALPageNotFoundException
   */
  @Override
  protected ALMailMessage selectDetail(RunData rundata, Context context) throws ALPageNotFoundException {
    try {
      String mailid = ALEipUtils.getTemp(rundata, context, ALEipConstants.ENTITY_ID);

      if (mailid == null || Integer.valueOf(mailid) == null) {
        // Mail IDが空の場合
        logger.debug("[Mail] Empty ID...");
        return null;
      }
      // change start 2012.2.8 受入障害対応No.272
      // return folder.getMail(Integer.valueOf(mailid));
      // change start 2012.2.24 受入障害No.294
      // return folder.getMail(Integer.valueOf(mailid), true);
      return folder.getMail(Integer.valueOf(mailid), true, ALMailUtils.USER_ACCOUNT);
      // change end 2012.2.24 受入障害No.294
      // change end 2012.2.8 受入障害対応No.272
    } catch (Throwable e) {
      logger.error("送信メール情報の詳細取得に失敗しました。", e);
      throw new ALPageNotFoundException();
    }
  }

  /**
   * ResultDataを取得する（メールの一覧） <BR>
   * 
   * @return Object メール一覧のResultData
   */
  @Override
  protected Object getResultData(AvzTMailSend record) {

    WebMailIndexRowResultData rd = new WebMailIndexRowResultData();
    rd.initField();

    // add start
    // メールファイルが存在しないデータは件名をリンクとしない
    ALLocalMailMessage msg = null;
    // メールファイルの内容を取得
    try {
      msg = ALMailUtils.readMail(folder.getFullName() + ALStorageService.separator() + record.getFilePath());
    } catch (Exception e) {
      logger.warn("メールファイルがありません。", e);
      msg = null;
    }
    if (null == msg) {
      // メールファイルがない場合はフラグON
      rd.setNoMailFile(true);
    } else {
      rd.setNoMailFile(false);
    }
    // add end

    rd.setMailId(record.getMailId().toString());

    // 状態
    String isRead = record.getReadFlg();
    if ("T".equals(isRead)) {
      // 既読
      rd.setReadImage("themes/" + getTheme() + "/images/icon/webmail_readmail.gif");
      rd.setReadImageDescription("既読");
      rd.setRead(false);
    } else {
      // 未読
      rd.setReadImage("themes/" + getTheme() + "/images/icon/webmail_unreadmail.gif");
      rd.setReadImageDescription("未読");
      rd.setRead(true);
    }

    String replyForward = record.getReplyForward();
    // 返信済メールの場合 状態に返信画像を設定
    if ("R".equals(replyForward)) {
      rd.setReadImage("images/webmail/webmail_reply_mail.gif");
      rd.setReadImageDescription("返信");
    }
    // 転送済メールの場合 状態に転送画像を設定
    if ("F".equals(replyForward)) {
      rd.setReadImage("images/webmail/webmail_forward_mail.gif");
      rd.setReadImageDescription("転送");
    }

    // 件名のデコード
    String subject = ALMailUtils.decodeSubject(record.getSubject());
    rd.setSubject(ALCommonUtils.compressString(subject, getStrLength()));

    // 受取人のデコード
    // 表示名<メールアドレス>のうち、表示名だけを設定
    // 表示名<メールアドレス>の形式になっていない場合はそのまま設定する
    // String[] person = MailUtility.decodeText(record.getPerson()).split("<");
    // rd.setPerson(person[0]);
    rd.setPerson("");
    InternetAddress[] persons = null;
    try {
      // change start 2012.5.22
      // persons =
      // MailUtility.parseAddresses(MailUtility.decodeText(record.getPerson()));
      // StringBuffer buf = new StringBuffer();
      // if (persons != null) {
      boolean isLegalAddressesFormat = true;
      StringBuffer buf = new StringBuffer();
      try {
        persons = MailUtility.parseAddresses(MailUtility.decodeText(record.getPerson()));
      } catch (Exception e) {
        logger.error("InternetAddressクラスでparseできない形式のメールアドレスです。Personレコードは" + record.getPerson() + "です。");
        isLegalAddressesFormat = false;
        buf.append(record.getPerson());
      }

      if (persons != null && isLegalAddressesFormat) {
        // change end 2012.5.22
        for (InternetAddress a : persons) {

          String tmp = null;

          // add start 受入テスト障害331
          tmp = WebMailUtils.getDisplayName(a.getAddress(), userId);
          if (tmp == null) {
            // add end
            if (a.getPersonal() == null) {
              tmp = a.getAddress();
            } else {
              tmp = a.getPersonal();
            }
            // add start
          }
          // add end

          if (tmp.indexOf(",") >= 0 || tmp.indexOf("\"") >= 0) {
            tmp = "\"" + tmp + "\"";
          }

          if (buf.length() == 0) {
            buf.append(tmp);
          } else {
            buf.append(", " + tmp);
          }
        }
      }
      rd.setPerson(ALCommonUtils.compressString(buf.toString(), 30));
    } catch (Exception e) {
      logger.error(e);
    }

    // 日付
    rd.setDate(record.getEventDate());
    // 容量
    rd.setFileVolume(record.getFileVolume().toString());

    // 添付ファイルの有無
    boolean hasAttachments = ("T".equals(record.getHasFiles()));
    // 添付ファイルがある場合は画像を設定
    if (hasAttachments) {
      rd.setWithFilesImage("images/webmail/webmail_withfiles.gif");
      rd.setWithFilesImageDescription("添付有");
    }
    rd.hasAttachments(hasAttachments);

    return rd;
  }

  /**
   * ResultDataを取得する（メール詳細） <BR>
   * 
   * @param obj
   * @return Object メール詳細のResultData
   */
  @Override
  protected Object getResultDataDetail(ALMailMessage obj) {
    WebMailResultData rd = null;
    try {
      ALLocalMailMessage msg = (ALLocalMailMessage) obj;

      String date = "";

      Date sentDate = msg.getSentDate();
      if (sentDate == null) {
        date = "Unknown";
      } else {
        date = ALMailUtils.translateDate(sentDate);
      }
      rd = new WebMailResultData();
      rd.initField();
      rd.setHeaders(msg.getHeaderArray());

      // change start 2011/12/20 IBM拡張文字対応
      // rd.setSubject(msg.getSubject());
      rd.setSubject(ALMailUtils.decodeSubject(msg.getHeader("Subject", null)));
      // change end
      rd.setFrom(ALMailUtils.getAddressString(msg.getFrom()));
      rd.setTo(ALMailUtils.getAddressString(msg.getRecipients(Message.RecipientType.TO)));
      rd.setDate(date);

      rd.setBody(msg.getBodyText());
      rd.setAttachmentFileNames(msg.getAttachmentFileNameArray());

      // add start
      Address[] ccs = msg.getRecipients(Message.RecipientType.CC);
      rd.setCc(ALMailUtils.getAddressString(ccs));

      Address[] bccs = msg.getRecipients(Message.RecipientType.BCC);
      rd.setBcc(ALMailUtils.getAddressString(bccs));
      // add end
    } catch (Exception e) {
      logger.error("Exception", e);
    }
    return rd;
  }

  /**
   * 現在選択されているタブを取得します。 <BR>
   * 
   * @return
   */
  public String getCurrentTab() {
    return currentTab;
  }

  /**
   * 現在のアカウントが持つメールフォルダを取得します。
   * 
   * @return
   */
  // change start 運用障害５８
  // public List<WebMailFolderResultData> getFolderList() {
  public List<ExtFolderInfo> getFolderList() {
    // change end
    return mailFolderList;
  }

  /**
   * @return
   * 
   */
  @Override
  protected Attributes getColumnMap() {
    return null;
  }

  /**
   * 
   * @return
   */
  public List<WebmailAccountLiteBean> getMailAccountList() {
    return mailAccountList;
  }

  /**
   * 現在選択中のアカウントIDを取得します。
   * 
   * @return
   */
  public int getAccountId() {
    return accountId;
  }

  /**
   * 現在選択中のフォルダIDを取得します。
   * 
   * @return
   */
  public int getFolderId() {
    return folderId;
  }

  public int getNewMailSum() {
    try {
      return WebMailUtils.getNewMailNumThread(orgId, user, accountId);
    } catch (Exception ex) {
      return 0;
    }
  }

  /**
   * フォルダ別未読メール数を取得する。
   * 
   * @return
   */
  public int getUnReadMailSumByFolderId(int folder_id) {
    return unreadMailSumMap.get(folder_id);
  }

  public String getFinalAccessDate() {
    return finalAccessDateStr;
  }

  /**
   * 表示する項目数を取得します。
   * 
   * @return
   */
  @Override
  public int getRowsNum() {
    return folder.getRowsNum();
  }

  /**
   * 総件数を取得します。
   * 
   * @return
   */
  @Override
  public int getCount() {
    return folder.getCount();
  }

  /**
   * 総ページ数を取得します。
   * 
   * @return
   */
  @Override
  public int getPagesNum() {
    return folder.getPagesNum();
  }

  /**
   * 現在表示されているページを取得します。
   * 
   * @return
   */
  @Override
  public int getCurrentPage() {
    return folder.getCurrentPage();
  }

  /**
   * 
   * @return
   */
  @Override
  public String getCurrentSort() {
    return folder.getCurrentSort();
  }

  /**
   * 
   * @return
   */
  @Override
  public String getCurrentSortType() {
    return folder.getCurrentSortType();
  }

  /**
   * @return
   */
  @Override
  public int getStart() {
    return folder.getStart();
  }

  /**
   * 
   * @param id
   * @return
   */
  public boolean isMatch(int id1, long id2) {
    return id1 == (int) id2;
  }

  /**
   * メール受信処理のメッセージを返します。
   * <p>
   * ログインユーザーの全アカウントに対して行います。<BR>
   * ※受信処理メッセージ <BR>
   * ・メールを受信中です <BR>
   * ・メールを受信しました etc
   * 
   * @return メール受信処理メッセージ
   * @throws Exception
   */
  public String getStatStr() throws Exception {
    // change start
    // ログインユーザーの全アカウント取得
    List<EipMMailAccount> accountList = WebMailUtils.getMailAccountNameList(userId);

    // 代理受信アカウントの取得
    List<AvzTMailSendRecvAcl> deputyList = new ArrayList<AvzTMailSendRecvAcl>();
    try {
      deputyList = ALMailUtils.getRepresentReceiveAccount(userId);
    } catch (Exception e) {
      logger.error("メール受信　代理受信アカウント取得に失敗しました。", e);
    }

    // アカウントIDリスト作成
    List<Integer> accountIdList = new ArrayList<Integer>();
    // ログインユーザーアカウント
    for (EipMMailAccount account : accountList) {
      accountIdList.add(account.getAccountId());
    }
    // 代理受信アカウント
    for (AvzTMailSendRecvAcl avzTMailSendRecvAcl : deputyList) {
      accountIdList.add(avzTMailSendRecvAcl.getAccountId());
    }

    String msg = null;
    StringBuffer statStr = new StringBuffer();

    // 全アカウントで受信メッセージ取得
    for (Integer accountId : accountIdList) {

      // 受信メッセージ取得
      msg = ALPop3MailReceiveThread.getReceiveMailResultStr(user, accountId);
      if (null != msg && msg.length() > 0) {
        if (statStr.length() > 0) {
          statStr.append("<br/>");
        }
        EipMMailAccount account = ALMailUtils.getMailAccount(accountId);
        statStr.append(account.getAccountName());
        statStr.append(" ");
        statStr.append(msg);

        if (null != msg && msg.equals("メールを受信しました。")) {
          msgList.add(account.getAccountName() + "に新着メールがあります。");
        }
      }
    }
    // return ALPop3MailReceiveThread.getReceiveMailResultStr(user, accountId);
    return statStr.toString();
  }

  // change end

  /**
   * @return
   */
  public List<ExtFolderInfo> getFolderHierarchyList() {
    return folder_hierarchy_list;
  }

  /**
   * @return
   */
  public ExtFolderInfo getSelectedFolder() {
    return selected_folderinfo;
  }

  /**
   * 検索ワード 本文を返す。<BR>
   * 
   * @return 検索ワード 本文
   */
  public ALStringField getSearchWord() {
    return searchWord;
  }

  /**
   * 検索ワード 件名を返す。<BR>
   * 
   * @return 検索ワード 件名
   */
  public ALStringField getSearchSubjectWord() {
    return searchSubjectWord;
  }

  /**
   * 検索ワード 受取人を返す。<BR>
   * 
   * @return 検索ワード 受取人
   */
  public ALStringField getSearchAddressWord() {
    return searchAddressWord;
  }

  /**
   * 検索 サブフォルダを含む を返す。<BR>
   * 
   * @return 検索ワード 差出人
   * @return
   */
  public ALStringField getIncludeSubFolder() {
    return includeSubFolder;
  }

  /**
   * ごみ箱フォルダIDを返す。<BR>
   * 
   * @return ごみ箱フォルダID
   */
  public int getTrashFolderId() {
    return trash_folder_id;
  }

  /**
   * １ユーザーあたりメールボックス容量上限を返す<BR>
   * 
   * @return mailBoxVolumeMax
   */
  public ALNumberField getMailBoxVolumeMax() {
    return mailBoxVolumeMax;
  }

  /**
   * メールボックス容量計を返す。<BR>
   * 
   * @return mailBoxVolumeSummary
   */
  public ALNumberField getMailBoxVolumeSummary() {
    return mailBoxVolumeSummary;
  }

  /**
   * メールボックス使用率を返す。<BR>
   * 
   * @return mailBoxVolumePct
   */
  public ALNumberField getMailBoxVolumePct() {
    return mailBoxVolumePct;
  }

  /**
   * メールボックス未使用率を返す。<BR>
   * 
   * @return mailBoxVolumeEmptyPct
   */
  public ALNumberField getMailBoxVolumeEmptyPct() {
    return mailBoxVolumeEmptyPct;
  }

  /**
   * メッセージリストを返す。<BR>
   * 
   * @return msgList
   * @throws Exception
   */
  public List<String> getMsgList() throws Exception {
    return msgList;
  }

  /**
   * 下書きアカウントフラグを返す。<BR>
   * 
   * @return isDraft
   */
  public boolean isDraft() {
    return isDraft;
  }

  /**
   * 代理受信アカウントフラグを返す。<BR>
   * 
   * @return isRepresent
   */
  public boolean isRepresent() {
    return isRepresent;
  }

}
