/*
 * Copyright 2016 Richard Cartwright
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * $Log: TimeStruct.java,v $
 * Revision 1.7  2011/07/27 17:20:31  vizigoth
 * Fractions of seconds now measured in 1/250ths.
 *
 * Revision 1.6  2011/01/05 13:09:06  vizigoth
 * Created new forge for making record and union type values.
 *
 * Revision 1.5  2009/05/14 16:15:24  vizigoth
 * Major refactor to remove dependency on JPA and introduce better interface and implementation separation. Removed all setPropertiesFromInterface and castFromInterface methods.
 *
 * Revision 1.4  2008/10/16 16:52:01  vizigoth
 * First early release 0.1.
 *
 * Revision 1.3  2008/01/14 20:52:23  vizigoth
 * Changed terminology for interfaces so that they all specify something.
 *
 * Revision 1.2  2007/12/14 15:01:49  vizigoth
 * Added to and edited document comments to a release level.
 *
 * Revision 1.1  2007/11/13 22:13:09  vizigoth
 * Public release of MAJ API.
 */

package tv.amwa.maj.record;

import tv.amwa.maj.integer.UInt8;

/** 
 * <p>Specifies the time component of date and time values specified according to 
 * Coordinated Universal Time (UTC), including
 * hour, minute, second and 1/250th of a second. The time structure is itself a component of a 
 * {@linkplain TimeStamp timestamp}.</p>
 *  
 * <p>To make values of this type, use the following methods from the 
 * {@linkplain tv.amwa.maj.industry.Forge MAJ forge}:</p>
 * 
 * <ul>
 *  <li>From its component parts: 
 *  {@link tv.amwa.maj.industry.Forge#makeTime(byte, byte, byte)} and
 *  {@link tv.amwa.maj.industry.Forge#makeTime(byte, byte, byte, byte)};</li>
 *  <li>From a {@link java.util.Calendar} value:
 *  {@link tv.amwa.maj.industry.Forge#makeTime(java.util.Calendar)};</li>
 *  <li>The time now: {@link tv.amwa.maj.industry.Forge#timeNow()};</li>
 *  <li>From a string representation as generated by {@link #toString()}: 
 *  {@link tv.amwa.maj.industry.Forge#parseTime(String)}.</li>
 * </ul>  
 *
 * @see TimeStamp
 * @see DateStruct
 * @see tv.amwa.maj.industry.TypeDefinitions#TimeStruct
 *
 *
*/
public interface TimeStruct { 

	/**
	 * <p>Set the values of the time structure using an hour, minute and second values 
	 * provided. The fraction of the second represented is set to be&nbsp;0.</p>
	 * 
	 * @param hour Hours component of the time value, represented in 24-hour clock format.
	 * @param minute Minutes component of the time value.
	 * @param second Seconds component of the time value.
	 * 
	 * @throws IllegalArgumentException One or more of the values is outside the acceptable
	 * range for a time value. 
	 */
	public void setTime(
			@UInt8 byte hour, 
			@UInt8 byte minute, 
			@UInt8 byte second)
		throws IllegalArgumentException;

	/**
	 * <p>Sets all the values of the time structure using the hour, minute, second and
	 * fraction of a second values provided.</p>
	 * 
	 * @param hour Hours component of the time value, represented in 24-hour clock format.
	 * @param minute Minutes component of the time value.
	 * @param second Seconds component of the time value.
	 * @param fraction Fractions of a second component of the time value, measured in 
	 * 1/250ths of a second.
	 *  
	 * @throws IllegalArgumentException One or more of the values is outside the acceptable
	 * range for a time value. 
	 */
	public void setTime(
			@UInt8 byte hour, 
			@UInt8 byte minute, 
			@UInt8 byte second, 
			@UInt8 byte fraction)
		throws IllegalArgumentException;
	
	/**
	 * <p>Returns the fractions of a second component of the time value, measured in 1/250ths of
	 * a second..</p>
	 * 
	 * @return Fractions of a second component of the time value.
	 */
	public @UInt8 byte getFraction();

	/**
	 * <p>Sets the fractions of a second component of the time value, meansured in 1/250ths of a
	 * second and so in the range 0&nbsp;to&nbsp;249.</p>
	 * 
	 * @param fraction Fractions of a second component of the time value.
	 *  
	 * @throws IllegalArgumentException The fractions of a second value is outside the acceptable
	 * range.
	 */
	public void setFraction(
			@UInt8 byte fraction)
		throws IllegalArgumentException;

	/**
	 * <p>Returns the hours component of the time value.</p>
	 * 
	 * @return Hours component of the time value.
	 */
	public @UInt8 byte getHour();

	/**
	 * <p>Sets the hours component of the time value, in the range 0&nbsp;to&nbsp;23.</p>
	 * 
	 * @param hour Hours component of the time value.
	 * 
	 * @throws IllegalArgumentException The hours value is outside the acceptable range.
	 */
	public void setHour(
			@UInt8 byte hour)
		throws IllegalArgumentException;

	/**
	 * <p>Returns the minutes component of the time value.</p>
	 * 
	 * @return Minutes component of the time value.
	 */
	public @UInt8 byte getMinute();

	/**
	 * <p>Sets the minutes component of the time value, in the range 0&nbsp;to&nbsp;59.</p>
	 * 
	 * @param minute Minutes component of the time value.
	 * 
	 * @throws IllegalArgumentException The minute value is outside the acceptable range.
	 */
	public void setMinute(
			@UInt8 byte minute)
		throws IllegalArgumentException;

	/**
	 * <p>Returns the seconds component of the time value. Note that advanced implementations
	 * may allow for very occasional leap second values of&nbsp;60 or&nbsp;61.</p>
	 * 
	 * @return Seconds component of the time value.
	 */
	public @UInt8 byte getSecond();

	/**
	 * <p>Sets the second component of the time value, normally in the range 0&nbsp;to&nbsp;59. Note that 
	 * advanced implementations may allow for very occasional leap second values of&nbsp;60 or&nbsp;61.</p>
	 * 
	 * @param second Seconds component of the time value.
	 * 
	 * @throws IllegalArgumentException The second value is outside the acceptable range.
	 */
	public void setSecond(
			@UInt8 byte second)
		throws IllegalArgumentException;
	
	/**
	 * <p>Create a cloned copy of this time value.</p>
	 * 
	 * @return Cloned copy of this time value.
	 */
	public TimeStruct clone();
	
	/** 
	 * <p>Formats a UTC-style string representation of the time structure's value, including the 
	 * timezone offset. The format used is "<code>HH:mm:ss.SSSZ</code>", where:</p>
	 * 
	 * <ul>
	 *  <li>"HH" is the two digit hour of the day in 24-hour clock;</li>
	 *  <li>"mm" is the two digit minute;</li>
	 *  <li>"ss" is the two digit second;</li>
	 *  <li>"SSS" is the three digital millisecond value to the nearest 1/250th of a second;</li>
	 *  <li>"Z" is the timezone offset from UTC, measure in positive or negative hours 
	 *  and minutes, e.g. "+0000" for GMT and "-0800" for PST.</li>
	 * </ul>
	 * 
	 * <p>The representation created by this method can be converted back to a time value by the 
	 * {@link tv.amwa.maj.industry.Forge#parseTime(String)} method.</p>
	 * 
	 * @return String representation of the time value according to the local time zone.
	 *
	 * @see tv.amwa.maj.industry.Forge#parseTime(String)
	 * @see java.text.SimpleDateFormat
	 */
	public String toString();
    
}
