/*
 * Copyright (C) 2005 - 2011 Jaspersoft Corporation. All rights reserved.
 * http://www.jaspersoft.com.
 *
 * Unless you have purchased  a commercial license agreement from Jaspersoft,
 * the following license terms  apply:
 *
 * 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.jaspersoft.jasperserver.api.engine.scheduling.domain;

import com.jaspersoft.jasperserver.api.JasperServerAPI;

import java.io.Serializable;
import java.util.Date;

/**
 * Abstract base class for report job triggers.
 * 
 * <p>
 * Job triggers determine when the report job is going to fire.
 * </p>
 * 
 * @author Lucian Chirita (lucianc@users.sourceforge.net)
 * @version $Id: ReportJobTrigger.java 19921 2010-12-11 14:52:49Z tmatyashovsky $
 * @see ReportJob#getTrigger()
 * @see ReportJobSimpleTrigger
 * @see ReportJobCalendarTrigger
 * @since 1.0
 */
@JasperServerAPI
public abstract class ReportJobTrigger implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * Start type that indicates that the job should be scheduled to start
	 * immediately.
	 * 
	 * @see #getStartType()
	 */
	public static final byte START_TYPE_NOW = 1;
	
	/**
	 * Start type that indicates that the job should be scheduled to start
	 * at the specified start date.
	 * 
	 * @see #getStartType()
	 * @see #getStartDate()
	 */
	public static final byte START_TYPE_SCHEDULE = 2;

	private long id;
	private int version = ReportJob.VERSION_NEW;
	private String timezone;
	private byte startType = START_TYPE_SCHEDULE;
	private Date startDate;
	private Date endDate;
	
	/**
	 * Creates an empty trigger.
	 */
	public ReportJobTrigger() {
	}

	/**
	 * Returns the ID of the trigger.
	 * 
	 * <p>
	 * The ID is automatically generated when the job is scheduled.
	 * </p>
	 * 
	 * @return the ID of the trigger
	 */
	public long getId() {
		return id;
	}

	/**
	 * Sets the ID of the trigger.
	 * 
	 * <p>
	 * The ID needs to be set when updating a report job, but not when saving
	 * a new job.
	 * </p>
	 * 
	 * @param id the trigger ID
	 */
	public void setId(long id) {
		this.id = id;
	}

	/**
	 * Returns the persistent version of this trigger.
	 * 
	 * <p>
	 * The version is automatically set when the trigger is retrieved
	 * (along with the job) from the scheduling service.
	 * </p>
	 * 
	 * @return the persistent trigger version 
	 * @see ReportJob#VERSION_NEW
	 */
	public int getVersion() {
		return version;
	}

	/**
	 * Sets the persistent trigger version.
	 * 
	 * <p>
	 * The version doesn't have to be set when saving a new report job,
	 * but it needs to be set when updating a report job (along with its trigger).
	 * </p>
	 * 
	 * @param version the persistent trigger version
	 */
	public void setVersion(int version) {
		this.version = version;
	}

	/**
	 * Returns the date at which the job should be scheduled to start.
	 * 
	 * <p>
	 * The start date can be <code>null</code> when the trigger start type
	 * is set to <code>START_TYPE_NOW</code>.
	 * </p>
	 * 
	 * @return the date at which the job is scheduled to start, or 
	 * <code>null</code> if the job is to start immediately
	 * @see #START_TYPE_SCHEDULE
	 */
	public Date getStartDate() {
		return startDate;
	}

	/**
	 * Sets the date at which the report job should be scheduled to start.
	 * 
	 * <p>
	 * When setting a start date, the start type should also be set to
	 * <code>START_TYPE_SCHEDULE</code>.
	 * </p>
	 * 
	 * @param startDate the date at which the report job should start. 
	 * @see #getStartDate()
	 * @see #START_TYPE_SCHEDULE
	 */
	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	/**
	 * Determines whether the job should be scheduled to start immediately,
	 * or at the specified start date.
	 * 
	 * @return the job start type
	 * @see #START_TYPE_NOW
	 * @see #START_TYPE_SCHEDULE
	 */
	public byte getStartType() {
		return startType;
	}

	/**
	 * Specify whether the job should be scheduled to start immediately,
	 * or at the specified start date.
	 * 
	 * <p>
	 * The job start date is not necessarily the date of the first execution.
	 * For calendar triggers, it's the date at which the trigger becomes
	 * effective and starts firing at the specified calendar moments.
	 * </p>
	 * 
	 * @param startType one of {@link #START_TYPE_NOW} and 
	 * {@value #START_TYPE_SCHEDULE}
	 */
	public void setStartType(byte startType) {
		this.startType = startType;
	}

	/**
	 * Returns the date at which job trigger should stop firing executions.
	 * 
	 * @return the trigger end date, or <code>null</code> if none set 
	 */
	public Date getEndDate() {
		return endDate;
	}

	/**
	 * Sets a date at which the trigger should cease firing job executions.
	 * 
	 * <p>
	 * Once the end date is reached, the job will not longer fire and will
	 * automatically be deleted.
	 * </p>
	 * 
	 * @param endDate an end date for the job
	 */
	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	/**
	 * Returns the timezone according to which the trigger date/time values
	 * are interpreted.
	 * 
	 *  <p>
	 *  If a timezone is not set for the trigger, the date/time values will be 
	 *  interpreted in the default server timezone.
	 *  </p>
	 * 
	 * @return the trigger timezone, or <code>null</code> if none set
	 */
	public String getTimezone() {
		return timezone;
	}

	/**
	 * Sets a timezone according to which trigger date/time values are
	 * interpreted.
	 * 
	 * @param timezone the trigger timezone 
	 */
	public void setTimezone(String timezone) {
		this.timezone = timezone;
	}
	

    /**
     * Compares two ReportJob triggers.
     *
     *
     * @param rjt the ReportJob trigger wich compares to this one
     * @return <code>true</code> if both triggers are equal
     */
	public boolean equals(ReportJobTrigger rjt) {
        return
            this.startType == rjt.getStartType() &&
            this.timezone.equals(rjt.getTimezone()) &&
            ((this.startDate == null && rjt.getStartDate() == null) ||
                (this.startDate != null && rjt.getStartDate() != null && this.startDate.compareTo(rjt.getStartDate()) == 0)) &&
            ((this.endDate == null && rjt.getEndDate() == null) ||
                (this.endDate != null && rjt.getEndDate() != null && this.endDate.compareTo(rjt.getEndDate()) == 0));
	}

}
