/**
* Kandata
* Copyright (C) 2003. Yoshinori Watanabe
* 
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* 
* This library 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
* Lesser General Public License for more details.
* 
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package roomreservation.server;

import java.util.*;
import java.io.*;
import java.net.URL;
import roomreservation.common.*;
import java.text.*;
import kandata.server.*;

/**
 * 会議室予約システム
 */
public class RoomReservation {

	static final String RESERVATION_PATH = "/reservation.tab";
	static final String ROOM_PATH = "/room.tab";
	private KandataServerContext serverContext;

	ArrayList roomList = new ArrayList();
	ArrayList reservationList = new ArrayList();

	public RoomReservation(KandataServerContext serverContext) {
		this.serverContext = serverContext;
	}
	public void init() throws Exception {
		System.out.println("RoomReservation.init()");
		roomList = loadRoomList();
		reservationList = loadReservationList();
	}
	public void exit(){
		storeReservationList();
	}
	/** 部屋情報を読み込む. */
	private ArrayList loadRoomList() throws IOException {
		ArrayList list = new ArrayList();
		BufferedReader reader = null;
		try {
			String path = serverContext.getResourcePath() + ROOM_PATH;
			System.out.println(path);
			reader = new BufferedReader(new FileReader(path));
			//reader = new BufferedReader(new FileReader(url.getFile()));
			while (reader.ready()) {
				String line = reader.readLine();
				if (line==null) break;
				StringTokenizer st = new StringTokenizer(line, "\t");
				while (st.hasMoreTokens()) {
					Room room = new Room();
					room.setName(st.nextToken());
					room.setTel(st.nextToken());
					list.add(room);
					System.out.println("room="+room.getName()+" "+room.getTel());
				}
			}
		}
		catch (IOException e) {
			e.printStackTrace();
			System.out.println("File(room.tab)="+new File("room.tab").getAbsolutePath());
			throw e;
		}
		finally {
			try { if (reader!=null) reader.close(); } catch (IOException e) {}
		}
		return list;
	}

	/** 予約情報を読み込む. */
	private ArrayList loadReservationList() {
		ArrayList list = new ArrayList();
		BufferedReader reader = null;
		try {
			String path = serverContext.getResourcePath() + RESERVATION_PATH;
			reader = new BufferedReader(new FileReader(path));
			while (reader.ready()) {
				String line = reader.readLine();
				if (line==null) break;
				StringTokenizer st = new StringTokenizer(line, "\t");
				while (st.hasMoreTokens()) {
					Reservation reserv = new Reservation();
					reserv.setName(st.nextToken());
					reserv.setRoomName(st.nextToken());
					reserv.setDate(st.nextToken());
					reserv.setStartTime(st.nextToken());
					reserv.setEndTime(st.nextToken());
					reserv.setMemo(st.nextToken());
					list.add(reserv);
				}
			}
		}
		catch (FileNotFoundException e) {
			// ファイルがなくてもOKとする。
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			try { if (reader!=null) reader.close(); } catch (IOException e) {}
		}
		return list;
	}

	/** 予約情報を読み込む. */
	private void storeReservationList() {
		PrintWriter writer = null;
		try {
			String path = serverContext.getResourcePath() + RESERVATION_PATH;
			writer = new PrintWriter(new BufferedWriter(new FileWriter(path)));
			for (int i=0; i<reservationList.size(); i++) {
				Reservation reserv = (Reservation) reservationList.get(i);
				writer.println(
					reserv.getName()+"\t"+
					reserv.getRoomName()+"\t"+
					reserv.getDate()+"\t"+
					reserv.getStartTime()+"\t"+
					reserv.getEndTime()+"\t"+
					reserv.getMemo());
			}
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		finally {
			if (writer!=null) writer.close();
		}
	}


	/**
	 * 部屋のリストを返します.
	 * 公開されたAPI
	 * @return Room の List
	 */
	public synchronized List getRoomList() {
		return roomList;
	}

	/**
	 * 部屋のリストを返します.
	 * 公開されたAPI
	 * @param day	取得したい日付("2003/05/25"の形式)
	 * @return Reservation の List
	 */
	public synchronized List getReservationList(String day) {
		ArrayList result = new ArrayList();
		for (int i=0; i<reservationList.size(); i++) {
			Reservation reserv = (Reservation) reservationList.get(i);
			if (reserv.getDate().equals(day)) {
				result.add(reserv);
			}
		}
		return result;
	}

	/**
	 * 予約を登録します.
	 * すでに同じ時間に予約が入っていた場合は失敗します。
	 * 公開されたAPI
	 * @param reserv	登録したい予約
	 * @return 予約が成功したか
	 */
	public synchronized boolean registReservation(Reservation reserv) {
		for (int i=0; i<reservationList.size(); i++) {
			Reservation r = (Reservation) reservationList.get(i);
			// 同じ日付で、同じ会議室か？
			if (r.getDate().equals(reserv.getDate()) && r.getRoomName().equals(reserv.getRoomName())) {
				// 開始時刻〜終了時刻が重なっているか？
				if (r.getStartTime().compareTo(reserv.getEndTime()) >= 0) continue;
				if (r.getEndTime().compareTo(reserv.getStartTime()) <= 0) continue;
				return false;
			}
		}
		reservationList.add(reserv);
		// ソート。
		Collections.sort(reservationList, new ReservationComparator());
		return true;
	}
	/** 予約をソートする. */
	private class ReservationComparator implements Comparator {
		public int compare(Object o1, Object o2) {
			Reservation r1 = (Reservation) o1;
			Reservation r2 = (Reservation) o2;
			if (! r1.getDate().equals(r2.getDate())) return r1.getDate().compareTo(r2.getDate());
			if (! r1.getRoomName().equals(r2.getRoomName())) return r1.getRoomName().compareTo(r2.getRoomName());
			return r1.getStartTime().compareTo(r2.getStartTime());
		}
	}
	/**
	 * 予約を削除します.
	 * 公開されたAPI
	 * @param reserv	削除したい予約
	 */
	public synchronized void cancelReservation(Reservation reserv) {
		reservationList.remove(reserv);
	}
}
