/*
 * Aipo is a groupware program developed by Aimluck,Inc.
 * Copyright (C) 2004-2008 Aimluck,Inc.
 * http://aipostyle.com/
 * 
 * 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.officecalendar;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.query.SelectQuery;
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;
import org.apache.turbine.services.TurbineServices;
import org.apache.turbine.util.RunData;

import com.aimluck.commons.field.ALDateTimeField;
/** Del 20110915 小濵 Start --- */
//import com.aimluck.eip.cayenne.om.portlet.EipTSchedule;
//import com.aimluck.eip.cayenne.om.portlet.EipTScheduleMap;
/** Del 20110915 小濵 End   --- */
import com.aimluck.eip.common.ALDBErrorException;
import com.aimluck.eip.common.ALPageNotFoundException;
import com.aimluck.eip.common.ALPermissionException;
import com.aimluck.eip.orm.DatabaseOrmService;
import com.aimluck.eip.officecalendar.beans.CellAppOfficecalendarBean;
import com.aimluck.eip.officecalendar.util.OfficecalendarUtils;
import com.aimluck.eip.services.accessctl.ALAccessControlConstants;
import com.aimluck.eip.services.accessctl.ALAccessControlFactoryService;
import com.aimluck.eip.services.accessctl.ALAccessControlHandler;
import com.aimluck.eip.util.ALEipUtils;

public class CellAppOfficecalendarSelectData {

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

	// 固有文字
	private final String START_DATE = "f";

	private final String END_DATE = "t";

	private final String SERVICE_TYPE = "s";

	// private final String LOGIN_ID = "i";

	// private final String PASS = "p";

	private final String TYPE_AIPO = "i";

	// error message

	private final String missing_startDate = "start date not be set";

	private final String missing_endDate = "end date not be set";

	private final String notForAipo = "request not for Aipo";

	private final String dateillegal = "date setting is illegal";

	private final String illegal_date = "illegal date error";

	// private final String loginError = "fail to login ,please do again";

	// 
	private DataContext dataContext;

	private String target_user_id;

	private ALDateTimeField startDate;

	private ALDateTimeField endDate;

	private List msgList;

	private ArrayList list;

	private List csvlist;

	private List allContainer;
	
	/** Add 20110908 小濵 Start --- */
    private Integer officeId;
    /** Add 20110908 小濵 End   --- */

	// ACL
	private String aclPortletFeature;

	public void init(RunData rundata) {

		dataContext = DatabaseOrmService.getInstance().getDataContext();
		target_user_id = String.valueOf(ALEipUtils.getUserId(rundata));
		startDate = new ALDateTimeField("yyyyMMddHHmmss") {
			protected String translateDate(Date date, String dateFormat) {
				if (date == null) {
					return "Unknown";
				}
				// 日付を表示形式に変換
				SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
				sdf.setLenient(true);
				sdf.setTimeZone(TimeZone.getDefault());
				return sdf.format(date);
			}
		};
		endDate = new ALDateTimeField("yyyyMMddHHmmss") {
			protected String translateDate(Date date, String dateFormat) {
				if (date == null) {
					return "Unknown";
				}
				// 日付を表示形式に変換
				SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
				sdf.setLenient(true);
				sdf.setTimeZone(TimeZone.getDefault());
				return sdf.format(date);
			}
		};
		msgList = new ArrayList();
		allContainer = new ArrayList();
		csvlist = new ArrayList();
		aclPortletFeature = ALAccessControlConstants.POERTLET_FEATURE_OFFICE_CALENDAR_SELF;

		/** Add 20110908 小濵 Start --- */
		officeId = rundata.getParameters().getInteger("target_user_id");
        /** Add 20110908 小濵 End   --- */
		if (rundata.getParameters().containsKey(START_DATE)) {
			StringBuffer start_date = new StringBuffer(rundata.getParameters()
					.getString(START_DATE));

			if (start_date.length() != 8)
				msgList.add(illegal_date);
			start_date.append("000000");
			startDate.setValue(start_date.toString());
		} else {
			msgList.add(missing_startDate);
		}

		if (rundata.getParameters().containsKey(END_DATE)) {
			StringBuffer end_date = new StringBuffer(rundata.getParameters()
					.getString(END_DATE));
			// ALDateTimeFieldのsetValue時のvalidateを変えるべきか？
			if (end_date.length() != 8)
				msgList.add(illegal_date);
			end_date.append("235959");
			endDate.setValue(end_date.toString());
		} else {
			msgList.add(missing_endDate);
		}

		if (rundata.getParameters().containsKey(SERVICE_TYPE)) {
			if (!rundata.getParameters().getString(SERVICE_TYPE).equals(
					TYPE_AIPO))
				msgList.add(notForAipo);
		}

	}

	public boolean validate() {
		startDate.validate((ArrayList) msgList);
		endDate.validate((ArrayList) msgList);
		if (msgList.size() != 0) {
			if (!(startDate.getValue().getTime() <= endDate.getValue()
					.getTime())) {
				msgList.add(dateillegal);
			}
			// debug
			System.out.println(msgList);
			return false;
		} else {
			return true;
		}
	}

	/** Del 20110915 小濵 Start --- */
//	public boolean getViewList(RunData rundata) {
//		try {
//			// ACL
//			doCheckAclPermission(rundata,
//					ALAccessControlConstants.VALUE_ACL_LIST);
//
//			List aList = selectList(rundata);
//			if (aList != null) {
//				list = new ArrayList();
//				Object obj = null;
//				int size = aList.size();
//				for (int i = 0; i < size; i++) {
//					obj = getResultData(aList.get(i));
//					if (obj != null) {
//						list.add(obj);
//					}
//				}
//			}
//
//			return (list != null);
//		} catch (ALPermissionException e) {
//			ALEipUtils.redirectPermissionError(rundata);
//			return false;
//		} catch (ALPageNotFoundException e) {
//			ALEipUtils.redirectPageNotFound(rundata);
//			return false;
//		} catch (ALDBErrorException e) {
//			ALEipUtils.redirectDBError(rundata);
//			return false;
//		}
//
//	}
	/** Del 20110915 小濵 End   --- */

	/** Del 20110915 小濵 Start --- */
//	private List selectList(RunData rundata) throws ALPageNotFoundException,
//			ALDBErrorException {
//		try {
//			SelectQuery query = getSelectQuery(rundata);
//			if (query == null)
//				return null;
//			List list = dataContext.performQuery(query);
//
//			return OfficecalendarUtils.sortByDummyOfficecalendar(list);
//		} catch (Exception e) {
//
//			// TODO: エラー処理
//			logger.error("[CellAppOfficecalendarSelectData]", e);
//			throw new ALDBErrorException();
//		}
//
//	}
	/** Del 20110915 小濵 End   --- */

	/** Del 20110915 小濵 Start --- */
//	private SelectQuery getSelectQuery(RunData rundata) {
//		SelectQuery query = new SelectQuery(EipTScheduleMap.class);
//
//		// 期間内のDayContainerの作成
//		/** Update 20110908 小濵 Start --- */
////		allContainer = getDayContainers(startDate.getValue(), endDate
////				.getValue());
//        allContainer = getDayContainers(startDate.getValue(), endDate
//            .getValue(), officeId);
//        /** Update 20110908 小濵 End   --- */
//		// 終了日時
//		Expression exp11 = ExpressionFactory.greaterOrEqualExp(
//				EipTScheduleMap.EIP_TSCHEDULE_PROPERTY + "."
//						+ EipTSchedule.END_DATE_PROPERTY, startDate.getValue());
//		// 開始日時
//		Expression exp12 = ExpressionFactory.lessOrEqualExp(
//				EipTScheduleMap.EIP_TSCHEDULE_PROPERTY + "."
//						+ EipTSchedule.START_DATE_PROPERTY, endDate.getValue());
//		// 通常スケジュール
//		Expression exp13 = ExpressionFactory.noMatchExp(
//				EipTScheduleMap.EIP_TSCHEDULE_PROPERTY + "."
//						+ EipTSchedule.REPEAT_PATTERN_PROPERTY, "N");
//		// 期間スケジュール
//		Expression exp14 = ExpressionFactory.noMatchExp(
//				EipTScheduleMap.EIP_TSCHEDULE_PROPERTY + "."
//						+ EipTSchedule.REPEAT_PATTERN_PROPERTY, "S");
//
//		query.setQualifier((exp11.andExp(exp12)).orExp(exp13.andExp(exp14)));
//
//		if ((target_user_id != null) && (!target_user_id.equals(""))) {
//			if (target_user_id
//					.startsWith(OfficecalendarUtils.TARGET_FACILITY_ID)) {
//				String fid = target_user_id.substring(
//						OfficecalendarUtils.TARGET_FACILITY_ID.length(),
//						target_user_id.length());
//				// 指定ユーザをセットする．
//				Expression exp1 = ExpressionFactory.matchExp(
//						EipTScheduleMap.USER_ID_PROPERTY, fid);
//				query.andQualifier(exp1);
//				// 設備のスケジュール
//				Expression exp2 = ExpressionFactory.matchExp(
//						EipTScheduleMap.TYPE_PROPERTY,
//						OfficecalendarUtils.SCHEDULEMAP_TYPE_FACILITY);
//				query.andQualifier(exp2);
//			} else {
//				// 指定ユーザをセットする．
//				Expression exp3 = ExpressionFactory.matchExp(
//						EipTScheduleMap.USER_ID_PROPERTY, Integer
//								.valueOf(target_user_id));
//				query.andQualifier(exp3);
//				// ユーザのスケジュール
//				Expression exp4 = ExpressionFactory.matchExp(
//						EipTScheduleMap.TYPE_PROPERTY,
//						OfficecalendarUtils.SCHEDULEMAP_TYPE_USER);
//				query.andQualifier(exp4);
//			}
//		} else {
//			// 表示できるユーザがいない場合の処理
//			return null;
//		}
//
//		// 開始日時でソート
//		query.addOrdering(EipTScheduleMap.EIP_TSCHEDULE_PROPERTY + "."
//				+ EipTSchedule.START_DATE_PROPERTY, true);
//		return query;
//	}
	/** Del 20110915 小濵 End   --- */

	/** Del 20110915 小濵 Start --- */
//	private Object getResultData(Object obj) throws ALPageNotFoundException,
//			ALDBErrorException {
//
//		OfficecalendarDetailResultData rd = new OfficecalendarDetailResultData();
//		rd.initField();
//		try {
//			EipTScheduleMap record = (EipTScheduleMap) obj;
//			EipTSchedule officecalendar = record.getEipTSchedule();
//			// スケジュールが棄却されている場合は表示しない
//			if ("R".equals(record.getStatus()))
//				return rd;
//			int userid_int = Integer.parseInt(target_user_id);
//
//			SelectQuery mapquery = new SelectQuery(EipTScheduleMap.class);
//			Expression mapexp1 = ExpressionFactory.matchExp(
//					EipTScheduleMap.SCHEDULE_ID_PROPERTY, officecalendar
//							.getScheduleId());
//			mapquery.setQualifier(mapexp1);
//			Expression mapexp2 = ExpressionFactory.matchExp(
//					EipTScheduleMap.USER_ID_PROPERTY, Integer
//							.valueOf(target_user_id));
//			mapquery.andQualifier(mapexp2);
//
//			List officecalendarmaps = dataContext.performQuery(mapquery);
//			boolean is_member = (officecalendarmaps != null && officecalendarmaps
//					.size() > 0) ? true : false;
//
//			// Dummy スケジュールではない
//			// 完全に隠す
//			// 自ユーザー以外
//			// 共有メンバーではない
//			// オーナーではない
//			if ((!"D".equals(record.getStatus()))
//					&& "P".equals(officecalendar.getPublicFlag())
//					&& (userid_int != record.getUserId().intValue())
//					&& (userid_int != officecalendar.getOwnerId().intValue())
//					&& !is_member)
//				return rd;
//
//			if ("C".equals(officecalendar.getPublicFlag())
//					&& (userid_int != record.getUserId().intValue())
//					&& (userid_int != officecalendar.getOwnerId().intValue())
//					&& !is_member) {
//				// 名前
//				rd.setName("非公開");
//				// 仮スケジュールかどうか
//				rd.setTmpreserve(false);
//			} else {
//				// 名前
//				rd.setName(officecalendar.getName());
//				// 仮スケジュールかどうか
//				rd.setTmpreserve("T".equals(record.getStatus()));
//			}
//			// ID
//			rd.setOfficecalendarId(officecalendar.getScheduleId().intValue());
//			// 親スケジュール ID
//			rd.setParentId(officecalendar.getParentId().intValue());
//			// 開始日時
//			rd.setStartDate(officecalendar.getStartDate());
//			// 終了日時
//			rd.setEndDate(officecalendar.getEndDate());
//			// 公開するかどうか
//			rd.setPublic("O".equals(officecalendar.getPublicFlag()));
//			// 非表示にするかどうか
//			rd.setHidden("P".equals(officecalendar.getPublicFlag()));
//			// ダミーか
//			rd.setDummy("D".equals(record.getStatus()));
//			// ログインユーザかどうか
//			rd.setLoginuser(record.getUserId().intValue() == userid_int);
//			// オーナーかどうか
//			rd.setOwner(officecalendar.getOwnerId().intValue() == userid_int);
//			// 共有メンバーかどうか
//			rd.setMember(is_member);
//			// 繰り返しパターン
//			rd.setPattern(officecalendar.getRepeatPattern());
//
//			//
//			rd.setNote(officecalendar.getNote());
//			rd.setPlace(officecalendar.getPlace());
//			addResultData(rd);
//
//		} catch (Exception e) {
//
//			// TODO: エラー処理
//			logger.error("Exception", e);
//
//			return null;
//		}
//		return rd;
//
//	}
	/** Del 20110915 小濵 End   --- */

    /** Update 20110908 小濵 Start */
//    private List getDayContainers(Date start, Date end) {
	private List getDayContainers(Date start, Date end, Integer officeId) {
    /** Update 20110908 小濵 End   */

		List list = new ArrayList();
		Calendar cals = Calendar.getInstance();
		Calendar cale = (Calendar) cals.clone();
		cals.setTime(start);
		cale.setTime(end);

		while (cals.before(cale)
				|| cals.getTimeInMillis() == cale.getTimeInMillis()) {
			OfficecalendarDayContainer con = new OfficecalendarDayContainer();
			con.initField();
	        /** Update 20110908 小濵 Start */
//            con.setDate(cals.getTime());
			con.setDate(cals.getTime(), officeId);
	        /** Update 20110908 小濵 End   */
			list.add(con);
			cals.add(Calendar.DATE, 1);
		}
		return list;
	}

	private void addResultData(OfficecalendarResultData rd) {
		int size = allContainer.size();

		// 期間用
		ALDateTimeField startDate = rd.getStartDate();
		ALDateTimeField endDate = rd.getEndDate();
		Calendar cals = Calendar.getInstance();
		Calendar cale = (Calendar) cals.clone();
		Calendar field_cal = (Calendar) cals.clone();
		cals.set(Integer.parseInt(startDate.getYear()), Integer
				.parseInt(startDate.getMonth()), Integer.parseInt(startDate
				.getDay()), 0, 0, 0);
		cale.set(Integer.parseInt(endDate.getYear()), Integer.parseInt(endDate
				.getMonth()), Integer.parseInt(endDate.getDay()), 0, 0, 0);

		for (int i = 0; i < size; i++) {
			OfficecalendarDayContainer con = (OfficecalendarDayContainer) allContainer
					.get(i);
			ALDateTimeField field = con.getDate();

			if (rd.getPattern().equals("S")) {
				if (cals.before(cale)) {
					// 期間スケジュールの期間
					field_cal.set(Integer.parseInt(field.getYear()), Integer
							.parseInt(field.getMonth()), Integer.parseInt(field
							.getDay()), 0, 0, 0);
					if (cals.getTimeInMillis() <= field_cal.getTimeInMillis()
							&& cale.getTimeInMillis() >= field_cal
									.getTimeInMillis()) {
						OfficecalendarDetailResultData rd3 = new OfficecalendarDetailResultData();
						rd3.initField();
						rd3.setOfficecalendarId((int) rd.getOfficecalendarId()
								.getValue());
						rd3.setParentId((int) rd.getParentId().getValue());
						rd3.setName(rd.getName().getValue());
						rd3.setStartDate(field_cal.getTime());
						rd3.setEndDate(field_cal.getTime());
						rd3.setTmpreserve(rd.isTmpreserve());
						rd3.setPublic(rd.isPublic());
						rd3.setHidden(rd.isHidden());
						rd3.setDummy(rd.isDummy());
						rd3.setLoginuser(rd.isLoginuser());
						rd3.setOwner(rd.isOwner());
						rd3.setMember(rd.isMember());
						rd3.setType(rd.getType());
						rd3.setNote(((OfficecalendarDetailResultData) rd)
								.getNoteStr());
						rd3.setPlace(((OfficecalendarDetailResultData) rd)
								.getPlace().getValue());
						con.addResultData(rd3);
					}
				} else {
					// 期間スケジュール一日
					if (field.getYear().equals(rd.getStartDate().getYear())
							&& field.getMonth().equals(
									rd.getStartDate().getMonth())
							&& field.getDay()
									.equals(rd.getStartDate().getDay())) {
						con.addResultData(rd);
						break;
					}
				}

				// 通常スケジュール
			} else if (!rd.getPattern().equals("N")) {
				// 繰り返しスケジュール
				if (OfficecalendarUtils.isView(con.getDate(), rd.getPattern(),
						rd.getStartDate().getValue(), rd.getEndDate()
								.getValue())) {
					Calendar temp = Calendar.getInstance();
					temp.setTime(field.getValue());
					temp.set(Calendar.HOUR, Integer.parseInt(rd.getStartDate()
							.getHour()));
					temp.set(Calendar.MINUTE, Integer.parseInt(rd
							.getStartDate().getMinute()));
					temp.set(Calendar.SECOND, 0);
					temp.set(Calendar.MILLISECOND, 0);
					Calendar temp2 = Calendar.getInstance();
					temp2.setTime(field.getValue());
					temp2.set(Calendar.HOUR, Integer.parseInt(rd.getEndDate()
							.getHour()));
					temp2.set(Calendar.MINUTE, Integer.parseInt(rd.getEndDate()
							.getMinute()));
					temp2.set(Calendar.SECOND, 0);
					temp2.set(Calendar.MILLISECOND, 0);
					OfficecalendarDetailResultData rd3 = new OfficecalendarDetailResultData();
					rd3.initField();
					rd3.setOfficecalendarId((int) rd.getOfficecalendarId()
							.getValue());
					rd3.setParentId((int) rd.getParentId().getValue());
					rd3.setName(rd.getName().getValue());
					// 開始日を設定し直す
					rd3.setStartDate(temp.getTime());
					// 終了日を設定し直す
					rd3.setEndDate(temp2.getTime());
					rd3.setTmpreserve(rd.isTmpreserve());
					rd3.setPublic(rd.isPublic());
					rd3.setHidden(rd.isHidden());
					rd3.setDummy(rd.isDummy());
					rd3.setLoginuser(rd.isLoginuser());
					rd3.setOwner(rd.isOwner());
					rd3.setMember(rd.isMember());
					rd3.setType(rd.getType());
					// 繰り返しはON
					rd3.setRepeat(true);

					//
					rd3.setNote(((OfficecalendarDetailResultData) rd)
							.getNoteStr());
					rd3.setPlace(((OfficecalendarDetailResultData) rd)
							.getPlace().getValue());

					con.addResultData(rd3);
				}
			} else if (field.getYear().equals(rd.getStartDate().getYear())
					&& field.getMonth().equals(rd.getStartDate().getMonth())
					&& field.getDay().equals(rd.getStartDate().getDay())) {
				con.addResultData(rd);
				break;
			}
		}

	}

	private boolean doCheckAclPermission(RunData rundata, int defineAclType)
			throws ALPermissionException {
		if (defineAclType == 0) {
			return true;
		}

		String pfeature = getAclPortletFeature();
		if (pfeature == null || "".equals(pfeature)) {
			return true;
		}

		ALAccessControlFactoryService aclservice = (ALAccessControlFactoryService) ((TurbineServices) TurbineServices
				.getInstance())
				.getService(ALAccessControlFactoryService.SERVICE_NAME);
		ALAccessControlHandler aclhandler = aclservice
				.getAccessControlHandler();

		boolean hasAuthority = aclhandler.hasAuthority(ALEipUtils
				.getUserId(rundata), pfeature, defineAclType);

		if (!hasAuthority) {
			throw new ALPermissionException();
		}

		return true;
	}

	public void doFormatCsv() {
		int size = allContainer.size();
		for (int i = 0; i < size; i++) {
			OfficecalendarDayContainer con = (OfficecalendarDayContainer) allContainer
					.get(i);
			List alist = con.getOfficecalendarList();
			int aSize = alist.size();
			for (int j = 0; j < aSize; j++) {
				OfficecalendarDetailResultData rd = (OfficecalendarDetailResultData) alist
						.get(j);
				CellAppOfficecalendarBean bean = new CellAppOfficecalendarBean();
				bean.initField();
				bean.setResultData(rd);
				csvlist.add(bean);
			}
		}
	}

	public String outPutCsv() {
		String LINE_SEPARATOR = System.getProperty("line.separator");
		StringBuffer sb = new StringBuffer();
		String delim = ",";
		List list = csvlist;
		int size = list.size();
		for (int i = 0; i < size; i++) {
			CellAppOfficecalendarBean bean = (CellAppOfficecalendarBean) list
					.get(i);
			String title = bean.getTitle();
			if (!title.equals("\"dummy\"")) {
				sb.append(bean.getStart_date()).append(delim);
				sb.append(bean.getEnd_date()).append(delim);
				sb.append(TYPE_AIPO).append(delim);
				sb.append(title).append(delim);
				sb.append(bean.getPlace()).append(delim);
				sb.append(bean.getText()).append(LINE_SEPARATOR);
			}
		}
		return sb.toString();
	}

	public List getMsgList() {
		return msgList;
	}

	public String getAclPortletFeature() {
		return aclPortletFeature;
	}

}