/*
 * 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.modules.actions.schedule;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.jetspeed.portal.portlets.VelocityPortlet;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.jetspeed.services.rundata.JetspeedRunData;
import org.apache.jetspeed.util.template.JetspeedLink;
import org.apache.jetspeed.util.template.JetspeedLinkFactory;
import org.apache.turbine.util.RunData;
import org.apache.velocity.context.Context;

import com.aimluck.commons.field.ALDateTimeField;
import com.aimluck.eip.cayenne.om.portlet.EipTScheduleMap;
import com.aimluck.eip.common.ALAbstractSelectData;
import com.aimluck.eip.common.ALEipConstants;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.modules.actions.common.ALBaseAction;
import com.aimluck.eip.schedule.CellScheduleFormDateData;
import com.aimluck.eip.schedule.CellScheduleFormGroupData;
import com.aimluck.eip.schedule.CellScheduleFormMemberData;
import com.aimluck.eip.schedule.CellScheduleFormNoteData;
import com.aimluck.eip.schedule.CellScheduleOnedaySelectByMemberData;
import com.aimluck.eip.schedule.CellScheduleOnedaySelectData;
import com.aimluck.eip.schedule.CellScheduleSelectByMemberData;
import com.aimluck.eip.schedule.CellScheduleSelectData;
import com.aimluck.eip.schedule.CellScheduleSelectFormByMemberData;
import com.aimluck.eip.schedule.CellScheduleSelectFormData;
import com.aimluck.eip.schedule.CellScheduleWeekSelectByMemberData;
import com.aimluck.eip.schedule.CellScheduleWeekSelectData;
import com.aimluck.eip.schedule.ScheduleChangeIndividualColorFormData;
import com.aimluck.eip.schedule.ScheduleChangeStatusFormData;
import com.aimluck.eip.schedule.ScheduleConst;
import com.aimluck.eip.schedule.ScheduleFormData;
import com.aimluck.eip.schedule.ScheduleOnedaySelectData;
import com.aimluck.eip.schedule.util.ScheduleUtils;
import com.aimluck.eip.util.ALEipUtils;

/**
 * スケジュールのアクションクラスです。
 * 
 */
public class CellScheduleAction extends ALBaseAction {

  /** <code>logger</code> logger */
  private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger(CellScheduleAction.class.getName());

  private final String[] weekday_str = { "", "(日)", "(月)", "(火)", "(水)", "(木)", "(金)", "(土)" };

  /**
   * 
   * @param portlet
   * @param context
   * @param rundata
   */
  @Override
  protected void buildNormalContext(VelocityPortlet portlet, Context context, RunData rundata) {
    ALEipUtils.removeTemp(rundata, context, "view_date_top");
  }

  /**
   * 
   * @param portlet
   * @param context
   * @param rundata
   */
  @Override
  protected void buildMaximizedContext(VelocityPortlet portlet, Context context, RunData rundata) {

    // MODEを取得
    String mode = rundata.getParameters().getString(ALEipConstants.MODE);
    try {
      if (ALEipConstants.MODE_FORM.equals(mode)) {
        doSchedule_form(rundata, context);
      } else if (ALEipConstants.MODE_DETAIL.equals(mode)) {
        doSchedule_detail(rundata, context);
        // add start 運用フェーズ課題・障害台帳No.159
      } else if (ALEipConstants.MODE_UPDATE.equals(mode)) {
        doSchedule_detail(rundata, context);
      } else if (ALEipConstants.MODE_DELETE.equals(mode)) {
        doSchedule_list(rundata, context);
        // add end
      } else if (ALEipConstants.MODE_LIST.equals(mode)) {
        // modify motegi start
        // doSchedule_list(rundata, context);
        String uid = ALEipUtils.getTemp(rundata, context, "target_otheruser_id");
        if (uid != null && !"".equals(uid)) {
          // 他メンバーのスケジュール⇒ToDoの後でスケジュールに戻った場合
          doSchedule_list_select_member(rundata, context);
          // ALEipUtils.removeTemp(rundata, context, "target_otheruser_id");
        } else {
          doSchedule_list(rundata, context);
        }
        // modify motegi end
      }
      if (getMode() == null) {
        // セッション削除
        if (ALEipUtils.getTemp(rundata, context, "view_date_top") != null && !ALEipUtils.getTemp(rundata, context, "view_date_top").equals("")) {
          ALEipUtils.removeTemp(rundata, context, "view_date_top");
        }
        // add start
        if (ALEipUtils.getTemp(rundata, context, "view_date") != null && !ALEipUtils.getTemp(rundata, context, "view_date").equals("")) {
          ALEipUtils.removeTemp(rundata, context, "view_date");
        }
        // add end

        // change start
        // 初期表示画面変更
        // doSchedule_menu(rundata, context);
        doSchedule_list(rundata, context);
        // change ned
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール(1日)一覧(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュールを一覧表示します。
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 自ユーザースケジュール1日を一覧表示します。
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_list(RunData rundata, Context context) {
    try {
      // ポートレット ID を取得する．
      String portletId = ((JetspeedRunData) rundata).getJs_peid();

      // 自ポートレットからのリクエストであれば、パラメータを展開しセッションに保存する。
      if (ALEipUtils.isMatch(rundata, context)) {
        // 現在選択されているタブ
        // oneday : １日表示
        // weekly : 週間表示
        // monthly: 月間表示
        if (rundata.getParameters().containsKey("tab")) {
          ALEipUtils.setTemp(rundata, context, "tab", rundata.getParameters().getString("tab"));
        }
      }

      String currentTab;
      ALAbstractSelectData<EipTScheduleMap, EipTScheduleMap> listData;
      String tmpCurrentTab = ALEipUtils.getTemp(rundata, context, "tab");
      if (tmpCurrentTab == null
        || !(tmpCurrentTab.equals("oneday") || tmpCurrentTab.equals("weekly") || tmpCurrentTab.equals("monthly") || tmpCurrentTab.equals("oneday-group") || tmpCurrentTab
          .equals("weekly-group"))) {
        currentTab = "oneday";
      } else {
        currentTab = tmpCurrentTab;
      }

      currentTab = ScheduleUtils.getCurrentTab(rundata, context);

      if (currentTab.equals("oneday")) {
        listData = new CellScheduleOnedaySelectData();
        ((ScheduleOnedaySelectData) listData).setPortletId(portletId);
        listData.initField();
        listData.doViewList(this, rundata, context);
        setTemplate(rundata, "schedule-list");
      }

    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール(1日)一覧(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // add start
  /**
   * (自ユーザー)日付指定用のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // add end
  public void doSchedule_form_selectday(RunData rundata, Context context) {
    try {
      CellScheduleSelectFormData formData = new CellScheduleSelectFormData();
      // formData.loadParameters(rundata, context);
      formData.initField();
      formData.doViewForm(this, rundata, context);

      setTemplate(rundata, "schedule-form-selectday");
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール表示日付指定(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * 日付指定用のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 自ユーザー日付指定後(スケジュール週一覧)のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_show_selectday(RunData rundata, Context context) {
    try {
      CellScheduleSelectFormData formData = new CellScheduleSelectFormData();
      formData.initField();
      // add start
      // (携帯・スマートフォン)カレンダー単体テスト不具合対応(S23)
      rundata.getParameters().setString("selected_day", "true");
      // add end
      setTemplate(rundata, "schedule-form-selectday");
      if (formData.doCheck(this, rundata, context)) {
        String viewdate = formData.getViewDateStr();
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_menu", "1")
          .addQueryData("start_date", viewdate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール一覧(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // *
  // * @param rundata
  // * @param context
  // * @param is_repeat
  // * @param is_span
  // * @param enable_entityid
  // * データベースから情報を取得する場合は，true．
  // */
  /**
   * スケジュール登録編集(1日,期間,日またぎ,繰り返し)を表示します
   * 
   * @param rundata
   * @param context
   * @param is_repeat
   * @param is_span
   * @param enable_entityid
   *            データベースから情報を取得する場合は，true．
   */
  // change end
  public void doSchedule_form(RunData rundata, Context context) {
    try {
      // add start
      // 任意参加メンバー判別用セッション格納値削除
      ALEipUtils.removeTemp(rundata, context, "is_submember");
      // add end
      CellScheduleFormDateData formData = new CellScheduleFormDateData();
      formData.loadParameters(rundata, context);
      formData.initField();
      formData.doViewForm(this, rundata, context);
      setTemplate(rundata, "schedule-form-date");
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール登録編集画面(携帯・スマートフォン)の表示に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 部署選択のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_form_group(RunData rundata, Context context) {
    try {
      CellScheduleFormGroupData formGroupData = new CellScheduleFormGroupData();
      formGroupData.loadParameters(rundata, context);
      formGroupData.initField();
      // add start
      // 遷移元(部署1,部署2)の判定
      if (rundata.getParameters().containsKey("from_post1")) {
        // 遷移元が部署1の場合
        if (formGroupData.doViewForm(this, rundata, context)) {
          // ゲットパラメータから部署1名を取得
          String current_parent_name = rundata.getParameters().getString(ScheduleConst.CURRENT_PARENT_GROUP_NAME);
          // セッションに部署1名を格納
          ALEipUtils.setTemp(rundata, context, ScheduleConst.CURRENT_PARENT_GROUP_NAME, current_parent_name);
          // コンテキストに部署1名をセット
          context.put(ScheduleConst.CURRENT_PARENT_GROUP_NAME, current_parent_name);
          // 部署2選択画面指定
          setTemplate(rundata, "schedule-form-group-post2");
        } else {
          // doViewFormでfalseだった場合は自画面遷移
          setTemplate(rundata, "schedule-form-group-post1");
        }
      } else {
        // 遷移元が部署1以外(スケジュール登録編集画面)の場合
        // add end
        if (formGroupData.doViewForm(this, rundata, context)) {
          // change start
          // setTemplate(rundata, "schedule-form-group");
          // 部署1選択画面を指定
          setTemplate(rundata, "schedule-form-group-post1");
          // change end
        } else {
          setTemplate(rundata, "schedule-form-date");
        }
      }

    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("部署一覧取得(携帯・スマートフォン)に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 部署選択(メンバー選択)のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_form_member(RunData rundata, Context context) {
    try {
      CellScheduleFormMemberData formGroupData = new CellScheduleFormMemberData();
      formGroupData.loadParameters(rundata, context);
      formGroupData.initField();
      if (formGroupData.doViewForm(this, rundata, context)) {
        // add star
        // 任意メンバーの選択の場合フラグをcontext(hidden項目)にセットする。
        String from_submeber = ALEipUtils.getTemp(rundata, context, "is_submember");
        if (null != from_submeber || "".equals(from_submeber)) {
          context.put("from_sub_member_flg", "true");
        }
        context.put("current_parent_group_name", rundata.getParameters().getString("current_parent_group_name"));
        // add end
        setTemplate(rundata, "schedule-form-member");
      } else {
        setTemplate(rundata, "schedule-form-group");
      }

    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("ユーザー一覧(携帯・スマートフォン)取得処理に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // remove start
  // ユーザー一覧ページング設計なしのため削除
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  // public void doSchedule_form_member_prev(RunData rundata, Context context) {
  // String prev = rundata.getParameters().getString("prev");
  // rundata.getParameters().setString("start", prev);
  //
  // doSchedule_form_member(rundata, context);
  // }
  //
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  // public void doSchedule_form_member_next(RunData rundata, Context context) {
  // String next = rundata.getParameters().getString("next");
  // rundata.getParameters().setString("start", next);
  //
  // doSchedule_form_member(rundata, context);
  // }

  // 共有施設選択は未使用のため削除
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  // public void doSchedule_form_facility(RunData rundata, Context context) {
  // try {
  // CellScheduleFormFacilityData formFacilityData =
  // new CellScheduleFormFacilityData();
  // formFacilityData.loadParameters(rundata, context);
  // formFacilityData.initField();
  // if (formFacilityData.doViewForm(this, rundata, context)) {
  // setTemplate(rundata, "schedule-form-facility");
  // } else {
  // setTemplate(rundata, "schedule-form-facility");
  // }
  //
  // } catch (Exception ex) {
  // logger.error("[CellScheduleAction] Exception.", ex);
  // ALEipUtils.redirectDBError(rundata);
  // }
  // }
  // remove end

  /**
   * スケジュール登録のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_form_note(RunData rundata, Context context) {
    try {
      CellScheduleFormNoteData formNoteData = new CellScheduleFormNoteData();
      // add start
      // 参加ユーザーチェック用フラグ
      rundata.getParameters().setString("to_form_note", "true");
      // add end
      formNoteData.loadParameters(rundata, context);
      formNoteData.initField();
      if (formNoteData.doViewForm(this, rundata, context)) {
        setTemplate(rundata, "schedule-form-note");
      } else {
        setTemplate(rundata, "schedule-form-date");
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール登録画面(携帯・スマートフォン)の表示に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールを登録します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_insert(RunData rundata, Context context) {
    try {
      CellScheduleFormNoteData formData = new CellScheduleFormNoteData();
      formData.initField();
      setTemplate(rundata, "schedule-form-note");
      if (formData.doInsert(this, rundata, context)) {
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        // change start
        // 追加後の遷移先変更
        // rundata.setRedirectURI(jsLink.getPortletById(
        // ALEipUtils.getPortlet(rundata, context).getID()).addQueryData(
        // "eventSubmit_doSchedule_menu",
        // "1").toString());
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .toString());
        // change end
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      } else {
        setTemplate(rundata, "schedule-form-note");
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュールの追加(携帯・スマートフォン)に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールを更新します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_update(RunData rundata, Context context) {
    try {
      CellScheduleFormNoteData formData = new CellScheduleFormNoteData();
      formData.initField();
      setTemplate(rundata, "schedule-form-date");
      if (formData.doUpdate(this, rundata, context)) {
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        // change start
        // 更新後の遷移先変更
        // rundata.setRedirectURI(jsLink.getPortletById(
        // ALEipUtils.getPortlet(rundata, context).getID()).addQueryData(
        // "eventSubmit_doSchedule_menu",
        // "1").toString());
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .toString());
        // change end
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      } else {
        setTemplate(rundata, "schedule-form-note");
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュールの更新(携帯・スマートフォン)に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュール削除のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_form_delete(RunData rundata, Context context) {
    try {
      CellScheduleSelectData detailData = new CellScheduleSelectData();
      detailData.init(this, rundata, context);
      detailData.initField();
      detailData.doViewDetail(this, rundata, context);
      setTemplate(rundata, "schedule-form-delete");
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール削除確認画面(携帯・スマートフォン)の表示に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールを削除します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_delete(RunData rundata, Context context) {
    try {
      CellScheduleFormNoteData formData = new CellScheduleFormNoteData();
      formData.loadParameters(rundata, context);
      formData.initField();
      setTemplate(rundata, "schedule-menu");

      if (formData.doDelete(this, rundata, context)) {
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        // change start
        // 削除後の遷移先変更
        // rundata.setRedirectURI(jsLink.getPortletById(
        // ALEipUtils.getPortlet(rundata, context).getID()).addQueryData(
        // "eventSubmit_doSchedule_menu",
        // "1").toString());
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .toString());
        // change end
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }

    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュールの削除(携帯・スマートフォン)に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールを詳細表示します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_detail(RunData rundata, Context context) {
    try {
      CellScheduleSelectData detailData = new CellScheduleSelectData();
      detailData.initField();
      detailData.doViewDetail(this, rundata, context);
      setTemplate(rundata, "schedule-detail");
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("スケジュール詳細(携帯・スマートフォン)の取得に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールの状態を変更します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_change_status(RunData rundata, Context context) {
    try {

      ScheduleChangeStatusFormData formData = new ScheduleChangeStatusFormData();
      formData.loadParametersViewDate(rundata, context);
      formData.initField();
      if (formData.doUpdate(this, rundata, context)) {
        String viewDate = formData.getViewDate().toString();
        setTemplate(rundata, "schedule-detail");
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        if (viewDate == null || viewDate.equals("")) {
          logger.error("[ScheduleAction] ALPageNotFoundException: View Date is wrong.");
          throw new ALPageNotFoundException();
        }

        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_detail", "1")
          .addQueryData("view_date", viewDate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      logger.error("[ScheduleAction] Exception.", ex);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュールのメニュー(週間スケジュール)を表示する．
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_menu(RunData rundata, Context context) {

    // add by motegi start
    clearScheduleSessionForSelectMember(rundata, context);
    // add by motegi end

    Calendar cal = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    List<String> weekly = new ArrayList<String>();
    List<String> weekday = new ArrayList<String>();

    ALDateTimeField date = new ALDateTimeField("yyyy-MM-dd");

    if (rundata.getParameters().getString("start_date") != null) {
      String str;
      str = rundata.getParameters().getString("start_date");
      date.setValue(str);
      cal.setTime(date.getValue());
      cal2.setTime(date.getValue());
    } else if (ALEipUtils.getTemp(rundata, context, "view_date_top") != null && !ALEipUtils.getTemp(rundata, context, "view_date_top").equals("")) {
      String str;
      str = ALEipUtils.getTemp(rundata, context, "view_date_top");
      date.setValue(str);
      cal.setTime(date.getValue());
      cal2.setTime(date.getValue());

      rundata.getParameters().setString("start_date", str);
    }

    for (int k = 0; k < 7; k++) {
      StringBuffer day = new StringBuffer();
      day.append(cal.get(Calendar.YEAR)).append("-").append(cal.get(Calendar.MONDAY) + 1).append("-").append(cal.get(Calendar.DATE));
      weekly.add(day.toString());
      weekday.add(weekday_str[cal.get(Calendar.DAY_OF_WEEK)]);

      cal.add(Calendar.DAY_OF_MONTH, 1);
    }
    cal2.add(Calendar.DAY_OF_MONTH, -7);
    ALEipUtils.setTemp(rundata, context, "view_date_top", weekly.get(0).toString());
    context.put("daylist", weekly);
    context.put("weekdaylist", weekday);
    date.setValue(cal.getTime());
    context.put("nextweek", date.toString());
    date.setValue(cal2.getTime());
    context.put("prevweek", date.toString());

    CellScheduleWeekSelectData selectdata = new CellScheduleWeekSelectData();
    selectdata.initField();
    selectdata.doViewList(this, rundata, context);
    context.put("now", selectdata.getNow());

    setTemplate(rundata, "schedule-menu");
  }

  // private void clearScheduleSession(RunData rundata, Context context) {
  // List list = new ArrayList();
  // list.add("entityid");
  // list.add("target_user_id");
  // ALEipUtils.removeTemp(rundata, context, list);
  // }

  // ////////////////////////add by motegi start

  private void clearScheduleSessionForSelectMember(RunData rundata, Context context) {
    ALEipUtils.removeTemp(rundata, context, "target_otheruser_id");
    ALEipUtils.removeTemp(rundata, context, "target_othergroup_name");
  }

  // change start
  // /**
  // * スケジュールのメニュー(週間スケジュール)を表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザー参照画面(部署1,2選択)を表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_form_selectgroup(RunData rundata, Context context) {
    try {
      // chnage start
      // 部署情報取得は、スケジュール参加ユーザ選択時に使用している
      // CellScheduleFormGroupDataクラスを使用する。
      // CellScheduleFormGroupForSelectData formGroupData =
      // new CellScheduleFormGroupForSelectData();
      // change end
      CellScheduleFormGroupData formGroupData = new CellScheduleFormGroupData();
      formGroupData.loadParameters(rundata, context);
      formGroupData.initField();
      // change start
      // formGroupData.doViewForm(this, rundata, context);
      // setTemplate(rundata, "schedule-form-select-group");
      // 遷移元(部署1,部署2)の判定
      if (rundata.getParameters().containsKey("from_post1")) {
        // 遷移元が部署1の場合
        if (formGroupData.doViewForm(this, rundata, context)) {
          // ゲットパラメータから部署1名を取得
          String current_parent_name = rundata.getParameters().getString(ScheduleConst.CURRENT_PARENT_GROUP_NAME);
          // セッションに部署1名を格納
          ALEipUtils.setTemp(rundata, context, ScheduleConst.CURRENT_PARENT_GROUP_NAME, current_parent_name);
          // コンテキストに部署1名をセット
          context.put(ScheduleConst.CURRENT_PARENT_GROUP_NAME, current_parent_name);
          // 部署2選択画面指定
          setTemplate(rundata, "schedule-select-group-post2");
        } else {
          // doViewFormでfalseだった場合は自画面遷移
          setTemplate(rundata, "schedule-select-group-post1");
        }
      } else {
        // 遷移元が部署1以外(スケジュール登録編集画面)の場合
        if (formGroupData.doViewForm(this, rundata, context)) {
          // 部署1選択画面を指定
          setTemplate(rundata, "schedule-select-group-post1");
        } else {
          doSchedule_list(rundata, context);
        }
      }
      // change end
    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("部署一覧取得(携帯・スマートフォン)に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュール登録のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザー参照画面(ユーザー選択)を表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_form_selectmember(RunData rundata, Context context) {
    try {
      // change start
      // 参加ユーザー選択処理クラスを使用
      // CellScheduleFormMemberForSelectData formGroupData =
      // new CellScheduleFormMemberForSelectData();
      CellScheduleFormMemberData formGroupData = new CellScheduleFormMemberData();
      // change end
      formGroupData.loadParameters(rundata, context);
      formGroupData.initField();
      formGroupData.doViewForm(this, rundata, context);
      setTemplate(rundata, "schedule-form-select-member");
    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("ユーザー一覧(携帯・スマートフォン)取得処理に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュールのメニュー(週間スケジュール)を表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザースケジュール(週間スケジュール)を表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_menu_select_member(RunData rundata, Context context) {
    Calendar cal = Calendar.getInstance();
    Calendar cal2 = Calendar.getInstance();
    List<String> weekly = new ArrayList<String>();
    List<String> weekday = new ArrayList<String>();

    ALDateTimeField date = new ALDateTimeField("yyyy-MM-dd");

    if (rundata.getParameters().getString("start_date") != null) {
      String str;
      str = rundata.getParameters().getString("start_date");
      date.setValue(str);
      cal.setTime(date.getValue());
      cal2.setTime(date.getValue());
    } else if (ALEipUtils.getTemp(rundata, context, "view_date_top") != null && !ALEipUtils.getTemp(rundata, context, "view_date_top").equals("")) {
      String str;
      str = ALEipUtils.getTemp(rundata, context, "view_date_top");
      date.setValue(str);
      cal.setTime(date.getValue());
      cal2.setTime(date.getValue());

      rundata.getParameters().setString("start_date", str);
    }

    for (int k = 0; k < 7; k++) {
      StringBuffer day = new StringBuffer();
      day.append(cal.get(Calendar.YEAR)).append("-").append(cal.get(Calendar.MONDAY) + 1).append("-").append(cal.get(Calendar.DATE));
      weekly.add(day.toString());
      weekday.add(weekday_str[cal.get(Calendar.DAY_OF_WEEK)]);

      cal.add(Calendar.DAY_OF_MONTH, 1);
    }
    cal2.add(Calendar.DAY_OF_MONTH, -7);
    ALEipUtils.setTemp(rundata, context, "view_date_top", weekly.get(0).toString());
    context.put("daylist", weekly);
    context.put("weekdaylist", weekday);
    date.setValue(cal.getTime());
    context.put("nextweek", date.toString());
    date.setValue(cal2.getTime());
    context.put("prevweek", date.toString());

    CellScheduleWeekSelectByMemberData selectdata = new CellScheduleWeekSelectByMemberData();
    selectdata.initField();
    selectdata.doViewList(this, rundata, context);
    context.put("now", selectdata.getNow());
    // 対象ユーザーをセッションに設定
    ALEipUtils.setTemp(rundata, context, "target_otheruser_id", selectdata.getTargerUser().getUserId().getValueAsString());
    setTemplate(rundata, "schedule-menu-select-member");
  }

  // change start
  // /**
  // * スケジュールを詳細表示します。
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザースケジュールの詳細表示をします。
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_detail_select_member(RunData rundata, Context context) {
    try {
      CellScheduleSelectByMemberData detailData = new CellScheduleSelectByMemberData();
      detailData.initField();
      detailData.doViewDetail(this, rundata, context);
      // setMode(ALEipConstants.MODE_LIST);
      setTemplate(rundata, "schedule-detail-select-member");
    } catch (Exception ex) {
      // change start
      // logger.error("[ScheduleAction] Exception.", ex);
      logger.error("他ユーザースケジュール詳細(携帯・スマートフォン)の取得に失敗しました。", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // add start
  /**
   * (他ユーザー)日付指定用のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // add end
  public void doSchedule_form_selectday_select_member(RunData rundata, Context context) {
    try {
      CellScheduleSelectFormByMemberData formData = new CellScheduleSelectFormByMemberData();
      formData.initField();
      formData.doViewForm(this, rundata, context);

      setTemplate(rundata, "schedule-form-selectday-select-member");
    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("スケジュール表示日付指定(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * 日付指定用のフォームを表示する．
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザー日付指定後(スケジュール週一覧)のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_show_selectday_select_member(RunData rundata, Context context) {
    try {
      CellScheduleSelectFormByMemberData formData = new CellScheduleSelectFormByMemberData();
      formData.initField();
      // add start
      // (携帯・スマートフォン)カレンダー単体テスト不具合対応(S122)
      rundata.getParameters().setString("selected_day", "true");
      // add end
      setTemplate(rundata, "schedule-form-selectday-select-member");
      if (formData.doCheck(this, rundata, context)) {
        String viewdate = formData.getViewDateStr();
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        rundata.setRedirectURI(jsLink.getPortletById(ALEipUtils.getPortlet(rundata, context).getID()).addQueryData(
          "eventSubmit_doSchedule_menu_select_member",
          "1").addQueryData("selectedmember", formData.getTargerUser().getUserId().getValueAsString()).addQueryData("start_date", viewdate).toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("他ユーザースケジュール一覧(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // change start
  // /**
  // * スケジュールを一覧表示します。
  // *
  // * @param rundata
  // * @param context
  // */
  /**
   * 他ユーザースケジュール一日を一覧表示します。
   * 
   * @param rundata
   * @param context
   */
  // change end
  public void doSchedule_list_select_member(RunData rundata, Context context) {
    try {
      // ポートレット ID を取得する．
      String portletId = ((JetspeedRunData) rundata).getJs_peid();

      // 自ポートレットからのリクエストであれば、パラメータを展開しセッションに保存する。
      if (ALEipUtils.isMatch(rundata, context)) {
        // 現在選択されているタブ
        // oneday : １日表示
        // weekly : 週間表示
        // monthly: 月間表示
        if (rundata.getParameters().containsKey("tab")) {
          ALEipUtils.setTemp(rundata, context, "tab", rundata.getParameters().getString("tab"));
        }
      }

      String currentTab;
      ALAbstractSelectData<EipTScheduleMap, EipTScheduleMap> listData;
      String tmpCurrentTab = ALEipUtils.getTemp(rundata, context, "tab");
      if (tmpCurrentTab == null
        || !(tmpCurrentTab.equals("oneday") || tmpCurrentTab.equals("weekly") || tmpCurrentTab.equals("monthly") || tmpCurrentTab.equals("oneday-group") || tmpCurrentTab
          .equals("weekly-group"))) {
        currentTab = "oneday";
      } else {
        currentTab = tmpCurrentTab;
      }

      currentTab = ScheduleUtils.getCurrentTab(rundata, context);

      if (currentTab.equals("oneday")) {
        listData = new CellScheduleOnedaySelectByMemberData();
        ((CellScheduleOnedaySelectByMemberData) listData).setPortletId(portletId);
        listData.initField();
        listData.doViewList(this, rundata, context);
        setTemplate(rundata, "schedule-list-select-member");
      }

    } catch (Exception ex) {
      // change start
      // logger.error("[CellScheduleAction] Exception.", ex);
      logger.error("他ユーザースケジュール(1日)一覧(携帯・スマートフォン)画面の表示に失敗しました", ex);
      // change end
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュール削除のフォームを表示する．
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_form_delete_select_member(RunData rundata, Context context) {
    try {
      CellScheduleSelectByMemberData detailData = new CellScheduleSelectByMemberData();
      detailData.init(this, rundata, context);
      detailData.initField();
      detailData.doViewDetail(this, rundata, context);
      setTemplate(rundata, "schedule-form-delete-select-member");
    } catch (Exception ex) {
      logger.error("[ScheduleAction] Exception.", ex);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  // add start
  /**
   * スケジュールの重要フラグ更新を行います。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_change_priority(RunData rundata, Context context) {
    ScheduleChangeStatusFormData formData = new ScheduleChangeStatusFormData();
    String mode = ScheduleChangeStatusFormData.UPDATING_PLACE_PRIORITY;
    formData.loadParametersViewDate(rundata, context);
    formData.initField();
    formData.setUpdatingPlace(mode);
    try {
      if (formData.doUpdate(this, rundata, context)) {
        String viewDate = formData.getViewDate().toString();
        setTemplate(rundata, "schedule-detail");
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        if (viewDate == null || viewDate.equals("")) {
          logger.error("[ScheduleAction] ALPageNotFoundException: View Date is wrong.");
          throw new ALPageNotFoundException();
        }
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_detail", "1")
          .addQueryData("view_date", viewDate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      logger.error("スケジュール(携帯・スマートフォン)マップの重要フラグ更新に失敗しました。", ex);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュール詳細の承諾更新処理を行います。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_change_status_consent(RunData rundata, Context context) {
    String status = rundata.getParameters().getString("consent");
    rundata.getParameters().setString("status", status);
    doSchedule_change_status(rundata, context);
  }

  /**
   * スケジュール詳細の仮承諾更新処理を行います。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_change_status_provisional(RunData rundata, Context context) {
    String status = rundata.getParameters().getString("provisional");
    rundata.getParameters().setString("status", status);
    doSchedule_change_status(rundata, context);
  }

  /**
   * スケジュール削除(ステータスが「辞退して削除しない」)確認画面を表示します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_veto(RunData rundata, Context context) {
    String status = rundata.getParameters().getString("veto");
    // context.put("status", status);
    rundata.getParameters().setString("status", status);
    doSchedule_change_status(rundata, context);
    // doSchedule_form_delete(rundata, context);
  }

  /**
   * スケジュール削除(ステータスが「返信せず削除」)確認画面を表示します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_remove_non(RunData rundata, Context context) {
    String status = rundata.getParameters().getString("remove-non");
    context.put("status", status);
    doSchedule_form_delete(rundata, context);
  }

  /**
   * スケジュール削除(ステータスが「辞退して削除する」)確認画面を表示します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_remove_veto(RunData rundata, Context context) {
    String status = rundata.getParameters().getString("remove-veto");
    context.put("status", status);
    doSchedule_form_delete(rundata, context);
  }

  /**
   * スケジュール(共有スケジュールの参加メンバーが削除する場合)を削除します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_delete_by_member(RunData rundata, Context context) {
    try {

      ScheduleChangeStatusFormData formData = new ScheduleChangeStatusFormData();
      formData.loadParametersViewDate(rundata, context);
      formData.initField();
      setTemplate(rundata, "schedule-menu");

      if (formData.doUpdate(this, rundata, context)) {
        String viewDate = formData.getViewDate().toString();
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        if (viewDate == null || viewDate.equals("")) {
          logger.error("[CellScheduleAction] ALPageNotFoundException: View Date is wrong.");
          throw new ALPageNotFoundException();
        }
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .addQueryData("view_date", viewDate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      logger.error("スケジュール(携帯・スマートフォン)の削除に失敗しました", ex);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * スケジュール(主催者が削除する場合)を削除します。
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_delete_by_owner(RunData rundata, Context context) {
    try {
      ScheduleFormData formData = new ScheduleFormData();
      // add start
      if (ScheduleConst.DEL_FLAG_0.equals(rundata.getParameters().getString(ScheduleConst.DEL_FLAG))) {
        rundata.getParameters().setString(ScheduleConst.DEL_MEMBER_FLAG, ScheduleConst.DEL_FLAG_0);
        rundata.getParameters().setString(ScheduleConst.DEL_RANGE_FLAG, ScheduleConst.DEL_FLAG_0);
      } else if (ScheduleConst.DEL_FLAG_1.equals(rundata.getParameters().getString(ScheduleConst.DEL_FLAG))) {
        rundata.getParameters().setString(ScheduleConst.DEL_MEMBER_FLAG, ScheduleConst.DEL_FLAG_0);
        rundata.getParameters().setString(ScheduleConst.DEL_RANGE_FLAG, ScheduleConst.DEL_FLAG_1);
      } else if (ScheduleConst.DEL_FLAG_2.equals(rundata.getParameters().getString(ScheduleConst.DEL_FLAG))) {
        rundata.getParameters().setString(ScheduleConst.DEL_MEMBER_FLAG, ScheduleConst.DEL_FLAG_1);
        rundata.getParameters().setString(ScheduleConst.DEL_RANGE_FLAG, ScheduleConst.DEL_FLAG_0);
      } else if (ScheduleConst.DEL_FLAG_3.equals(rundata.getParameters().getString(ScheduleConst.DEL_FLAG))) {
        rundata.getParameters().setString(ScheduleConst.DEL_MEMBER_FLAG, ScheduleConst.DEL_FLAG_1);
        rundata.getParameters().setString(ScheduleConst.DEL_RANGE_FLAG, ScheduleConst.DEL_FLAG_1);
      }
      // add end
      formData.loadParametersViewDate(rundata, context);
      formData.initField();
      setTemplate(rundata, "schedule-menu");

      if (formData.doDelete(this, rundata, context)) {
        String viewDate = formData.getViewDate().toString();
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        if (viewDate == null || viewDate.equals("")) {
          logger.error("[CellScheduleAction] ALPageNotFoundException: View Date is wrong.");
          throw new ALPageNotFoundException();
        }
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .addQueryData("view_date", viewDate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      }
    } catch (Exception ex) {
      logger.error("スケジュール(携帯・スマートフォン)の削除に失敗しました。", ex);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * 部署選択(任意メンバー選択)のフラグをセットする．
   * 
   * @param rundata
   * @param context
   */
  public void doSchedule_form_group_from_sub_member(RunData rundata, Context context) {
    // 必須、任意の判定処理用にセッションに格納する
    ALEipUtils.setTemp(rundata, context, "is_submember", "true");
    doSchedule_form_group(rundata, context);
  }

  // add end
  // add start 要件No.26 スケジュール個別色換え
  /**
   * 分類選択画面を開く
   * 
   * @param rundata
   *            実行データ
   * @param context
   *            Velocityコンテキスト
   */
  public void doSchedule_form_color(RunData rundata, Context context) {
    try {
      ScheduleChangeIndividualColorFormData formData = new ScheduleChangeIndividualColorFormData();
      formData.setMobile(true);
      formData.doViewForm(this, rundata, context);
      setTemplate(rundata, "schedule-form-color");
    } catch (Exception e) {
      logger.error("分類設定画面の表示に失敗しました", e);
      ALEipUtils.redirectDBError(rundata);
    }
  }

  /**
   * 個別色を選択した色分類で更新する
   * 
   * @param rundata
   *            実行データ
   * @param context
   *            Velocityコンテキスト
   */
  public void doSchedule_change_color(RunData rundata, Context context) {
    try {
      // 個別色変更を実行
      ScheduleChangeIndividualColorFormData formData = new ScheduleChangeIndividualColorFormData();
      formData.setMobile(true);
      if (formData.doUpdate(this, rundata, context)) {
        // 成功した場合はスケジュール（1日）へ遷移する
        String viewDate = formData.getCellViewDate().toString();
        JetspeedLink jsLink = JetspeedLinkFactory.getInstance(rundata);
        if (viewDate == null || viewDate.equals("")) {
          logger.error("予定表示日が存在しないため、画面を開けません。");
          throw new ALPageNotFoundException();
        }
        rundata.setRedirectURI(jsLink
          .getPortletById(ALEipUtils.getPortlet(rundata, context).getID())
          .addQueryData("eventSubmit_doSchedule_list", "1")
          .addQueryData("view_date", viewDate)
          .toString());
        rundata.getResponse().sendRedirect(rundata.getRedirectURI());
        jsLink = null;
      } else {
        // エラー時は分類画面を再表示
        setTemplate(rundata, "schedule-form-color");
      }
    } catch (Exception e) {
      logger.error("個別色の変更に失敗しました", e);
      ALEipUtils.redirectDBError(rundata);
    }
  }
  // add end
}
