package org.springframework.prospring.ticket.service;

import java.math.*;
import java.util.*;

import org.springframework.prospring.ticket.domain.*;

/**
 * Reprezentuje żądanie rezerwacji. Jest to żądanie dotyczące zarezerwowania podanej ilości 
 * miejsc na konkretny spekatkl.
 */
public class ReservationRequest {

    private static final long MILLIS_PER_MINUTE = 1000L * 60L;

    // spektakl.
    private Performance performance;

    // ilość żądanych miejsc.
    private int numberOfSeatsRequested;

    // grupa cenowa żądanych miejsc.
    private PriceBand priceBand;

    // data określająca do kiedy miejsca będą zarezerwowane w ramach danej rezerwacji.
    private Date holdUntil;

    // ilość minut określając jak długo rezerwacja będzie ważna.
    private int minutesToHold;

    // opłata za obsługę rezerwacji.
    private BigDecimal bookingFee = new BigDecimal(0);

    /**
     *          
     */
    public ReservationRequest() {
    }

    /**
     * Konstruktor - tworzy nowe żądanie rezerwacji.
     * @param performance Spektakl, którego dotyczy rezerwacja.
     * @param priceBand Grupa cenowa miejsc.
     * @param numberOfSeatsRequested Ilość rezerwowanych miejsc.
     * @param minutesToHold Ilość minut na jakie miejsca zostaną zarezerwowane.
     */
    public ReservationRequest(
        Performance performance,
        PriceBand priceBand,
        int numberOfSeatsRequested,
        int minutesToHold) {

        this.performance = performance;
        this.priceBand = priceBand;
        this.numberOfSeatsRequested = numberOfSeatsRequested;
        holdFor(minutesToHold);
    }

    /**
     * Zwraca datę określająca do kiedy miejsca będą zarezerwowane jeśli nie zostanie wykonane zamówienie.
     * @return Data określająca do kiedy miejsca będą zarezerwowane jeśli nie zostanie dokonane zamówienie.
     */
    public Date getHoldUntil() {
        return holdUntil;
    }

    /**
     * Zwraca ilość minut określająca jak długo miejsca będą zarezerwowane jeśli nie zostanie wykonane zamówienie.
     * @return Ilość minut określająca jak długo miejsca będą zarezerwowane jeśli nie zostanie wykonane zamówienie.
     */
    public int getMinutesToHold() {
        return minutesToHold;
    }

    /**
     * Ustawia ilość minut określającą jak długo miejsca będą zarezerwowane jeśli nie zostanie wykonane zamówienie.
     * @param minutes Ilość minut określająca jak długo miejsca będą zarezerwowane jeśli nie zostanie wykonane zamówienie.
     */
    public void holdFor(int minutes) {
        minutesToHold = minutes;
        holdUntil = new Date(System.currentTimeMillis() + minutes * MILLIS_PER_MINUTE);
    }

    /**
     * Zwraca spektakl skojarzony z tym żądaniem.
     * @return Spektakl skojarzony z tym żądaniem.
     */
    public Performance getPerformance() {
        return performance;
    }

    /**
     * Ustawia spektakl skojarzony z tym żądaniem.
     * @param performance Spektakl skojarzony z tym żądaniem.
     */
    public void setPerformance(Performance performance) {
        this.performance = performance;
    }

    /**
     * Zwraca ilość miejsc skojarzoną z tym żądaniem.
     * @return Ilość miejsc skojarzona z tym żądaniem.
     */
    public int getNumberOfSeatsRequested() {
        return numberOfSeatsRequested;
    }

    /**
     * Ustawia ilość miejsc skojarzoną z tym żądaniem.
     * @param numberOfSeatsRequested Ilość miejsc skojarzona z tym żądaniem.
     */
    public void setNumberOfSeatsRequested(int numberOfSeatsRequested) {
        this.numberOfSeatsRequested = numberOfSeatsRequested;
    }

    /**
     * Zwraca grupę cenową rezerwowanych miejsc.
     * @return Grupa cenowa rezerwowanych miejsc.
     */
    public PriceBand getPriceBand() {
        return priceBand;
    }

    /**
     * Ustawia grupę cenową rezerwowanych miejsc.
     * @param priceBand Grupa cenowa rezerwowanych miejsc.
     */
    public void setPriceBand(PriceBand priceBand) {
        this.priceBand = priceBand;
    }

    /**
     * Zwraca opłatę za obsługę rezerwacji.
     * @return Opłata za obsługę rezerwacji.
     */
    public BigDecimal getBookingFee() {
        return bookingFee;
    }

    /**
     * Ustawia opłatę za obsługę rezerwacji.
     * @param bookingFee Opłata za obsługę rezerwacji.
     */
    public void setBookingFee(BigDecimal bookingFee) {
        this.bookingFee = bookingFee;
    }

}
