/* ======================================================================
   Parts Copyright 2006 University of Leeds, Oxford University, University of the Highlands and Islands.

   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.

====================================================================== */

package org.bodington.logbook.server;

import java.sql.Timestamp;
import java.util.Enumeration;

import org.bodington.server.BuildingServerException;
import org.bodington.sqldatabase.SqlPersistentObject;
import org.bodington.text.BigString;
import org.bodington.database.PrimaryKey;

/**
 * This object represents the set of log book entries made under a single person's
 * name.  Typically represents the entries of a single student.
 * 
 * @author Jon Maber
 */
public class LogBookPage extends SqlPersistentObject
	{
	private static final int FLAG_CLOSED	= 1;
	
	private PrimaryKey log_book_page_id;
	private PrimaryKey log_book_id;
	private PrimaryKey user_id;
	private int flags;
	private java.sql.Timestamp when_first;
	private java.sql.Timestamp when_last;
	private java.sql.Timestamp when_user_first;
	private java.sql.Timestamp when_user_last;
	private PrimaryKey section_first_big_string_id;
	private PrimaryKey section_last_big_string_id;
	private PrimaryKey section_user_first_big_string_id;
	private PrimaryKey section_user_last_big_string_id;
	private PrimaryKey question_first_big_string_id;
	private PrimaryKey question_last_big_string_id;
	private PrimaryKey question_user_first_big_string_id;
	private PrimaryKey question_user_last_big_string_id;
        private PrimaryKey acl_id;
	
	
    /**
     * Simply redirects to getLogBookPageId().
     * 
     * @return The primary key of the object.
     */
    public PrimaryKey getPrimaryKey()
    	{
        return getLogBookPageId();
    	}

    /**
     * Called only by bodington database code when loading an object from
     * the database or inserting a new record in the database.
     * 
     * @param key The primary key of the object.
     */
    public void setPrimaryKey(PrimaryKey key)
    	{
    	setLogBookPageId( key );
    	}


	/**
	 * Gets the unique id of the LogBookPage.
	 * 
	 * @return A PrimaryKey.
	 */
	public PrimaryKey getLogBookPageId()
		{
		return log_book_page_id;
		}
		
	/**
	 * Called only when the object is loaded from the database
	 * or a new object is saved.
	 * 
	 * @param id The primary key from the database.
	 */
	public void setLogBookPageId( PrimaryKey id )
		{
		log_book_page_id = id;
		}
		
	/**
	 * Which log book does this page 
	 * belong to.
	 * 
	 * @return The id of the log book.
	 */
	public PrimaryKey getLogBookId()
		{
		return log_book_id;
		}
		
	/**
	 * When creating a new page or loading a page from the 
	 * database, sets the id of the logbook this page belongs to.
	 * 
	 * @param id The id of the logbook page.
	 */
		
	public void setLogBookId( PrimaryKey id )
		{
		log_book_id = id;
		}


	/**
	 * Gets the id of the user with whom the page is associated.
	 * 
	 * @return Id number of the user.
	 */
	public PrimaryKey getUserId()
		{
		return user_id;
		}
		
	/**
	 * When making a new entry or loading an entry from the
	 * database, indicated who the page is associated with.
	 * 
	 * @param id The user id.
	 */
	public void setUserId( PrimaryKey id )
		{
		user_id = id;
		}


		
		
	/**
	 * Gets the date/time that this log book page first had 
	 * an entry made to it.
	 * 
	 * @return An SQL timestamp value.
	 */
	public Timestamp getWhenFirst()
		{
		return when_first;
		}
		
	/**
	 * Sets the date/time that this log book page first had 
	 * an entry made to it.
	 * 
	 * @param t An SQL timestamp value.
	 */
	public void setWhenFirst( Timestamp t )
		{
		when_first = t;
		setUnsaved();
		}
		
	/**
	 * Gets the date/time that this log book page last had 
	 * an entry made to it.
	 * 
	 * @return An SQL timestamp value.
	 */
	public Timestamp getWhenLast()
		{
		return when_last;
		}
		
	/**
	 * Sets the date/time that this log book page last had 
	 * an entry made to it.
	 * 
	 * @param t An SQL timestamp value.
	 */
	public void setWhenLast( Timestamp t )
		{
		when_last = t;
		setUnsaved();
		}
		
		
	/**
	 * Gets the date/time that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return An SQL timestamp value.
	 */
	public Timestamp getWhenUserFirst()
		{
		return when_user_first;
		}
		
	/**
	 * Sets the date/time that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param t An SQL timestamp value.
	 */
	public void setWhenUserFirst( Timestamp t )
		{
		when_user_first = t;
		setUnsaved();
		}
		
	/**
	 * Gets the date/time that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return An SQL timestamp value.
	 */
	public Timestamp getWhenUserLast()
		{
		return when_user_last;
		}
		
	/**
	 * Sets the date/time that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param t An SQL timestamp value.
	 */
	public void setWhenUserLast( Timestamp t )
		{
		when_user_last = t;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the section that this log book page first had 
	 * an entry made to it.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getSectionFirstBigStringId()
		{
		return section_first_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the section that this log book page first had 
	 * an entry made to it.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setSectionFirstBigStringId( PrimaryKey k )
		{
		section_first_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the section that this log book page last had 
	 * an entry made to it.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getSectionLastBigStringId()
		{
		return section_last_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the section that this log book page last had 
	 * an entry made to it.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setSectionLastBigStringId( PrimaryKey k )
		{
		section_last_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the section that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getSectionUserFirstBigStringId()
		{
		return section_user_first_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the section that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setSectionUserFirstBigStringId( PrimaryKey k )
		{
		section_user_first_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the section that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getSectionUserLastBigStringId()
		{
		return section_user_last_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the section that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setSectionUserLastBigStringId( PrimaryKey k )
		{
		section_user_last_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the question that this log book page first had 
	 * an entry made to it.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getQuestionFirstBigStringId()
		{
		return question_first_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the question that this log book page first had 
	 * an entry made to it.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setQuestionFirstBigStringId( PrimaryKey k )
		{
		question_first_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the question that this log book page last had 
	 * an entry made to it.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getQuestionLastBigStringId()
		{
		return question_last_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the question that this log book page last had 
	 * an entry made to it.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setQuestionLastBigStringId( PrimaryKey k )
		{
		question_last_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the question that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getQuestionUserFirstBigStringId()
		{
		return question_user_first_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the question that this log book page first had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setQuestionUserFirstBigStringId( PrimaryKey k )
		{
		question_user_first_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Gets the big string ID of the question that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @return Primary key of the big_string entry.
	 */
	public PrimaryKey getQuestionUserLastBigStringId()
		{
		return question_user_last_big_string_id;
		}
		
	/**
	 * Sets the big string ID of the question that this log book page last had 
	 * an entry made to it by the user themselves.
	 * 
	 * @param k Primary key of the big_string entry.
	 */
	public void setQuestionUserLastBigStringId( PrimaryKey k )
		{
		question_user_last_big_string_id = k;
		setUnsaved();
		}
		
	/**
	 * Get an integer containing all the flags for this log book.  Mainly
	 * used by the Bodington system when saving this object to the database.
	 * 
	 * @return An integer representing up to 32 flags.
	 */
	public int getFlags()
		{
		return flags;
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getSectionFirst()
		throws BuildingServerException
		{
		return stringFromBigStringId( section_first_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setSectionFirst( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( section_first_big_string_id, s );
                if ( !(k == section_first_big_string_id) )
                        {
			section_first_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getSectionLast()
		throws BuildingServerException
		{
		return stringFromBigStringId( section_last_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setSectionLast( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( section_last_big_string_id, s );
                if ( !(k == section_last_big_string_id) )
                        {
			section_last_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getSectionUserFirst()
		throws BuildingServerException
		{
		return stringFromBigStringId( section_user_first_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setSectionUserFirst( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( section_user_first_big_string_id, s );
                if ( !(k == section_user_first_big_string_id) )
                        {
			section_user_first_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getSectionUserLast()
		throws BuildingServerException
		{
		return stringFromBigStringId( section_user_last_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setSectionUserLast( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( section_user_last_big_string_id, s );
                if ( !(k == section_user_last_big_string_id) )
                        {
			section_user_last_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getQuestionFirst()
		throws BuildingServerException
		{
		return stringFromBigStringId( question_first_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setQuestionFirst( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( question_first_big_string_id, s );
                if ( !(k == question_first_big_string_id) )
                        {
			question_first_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getQuestionLast()
		throws BuildingServerException
		{
		return stringFromBigStringId( question_last_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setQuestionLast( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( question_last_big_string_id, s );
                if ( !(k == question_last_big_string_id) )
                        {
			question_last_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getQuestionUserFirst()
		throws BuildingServerException
		{
		return stringFromBigStringId( question_user_first_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setQuestionUserFirst( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( question_user_first_big_string_id, s );
                if ( !(k == question_user_first_big_string_id) )
                        {
			question_user_first_big_string_id = k;
			setUnsaved();
			}
		}

	/**
	 * Convenience method that loads the BigString object that
	 * is referenced by the appropriate property.
	 * 
	 * @return Text of the entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public String getQuestionUserLast()
		throws BuildingServerException
		{
		return stringFromBigStringId( question_user_last_big_string_id );
		}
		
	/**
	 * Convenience method that finds the big string entry
	 * referenced by the appropriate property and changes its text
	 * value.
	 * 
	 * @param s The new text for this entry.
	 * @exception org.bodington.server.BuildingServerException
	 */
	public void setQuestionUserLast( String s )
		throws BuildingServerException
		{
                PrimaryKey k = insertOrUpdateBigString( question_user_last_big_string_id, s );
                if ( !(k == question_user_last_big_string_id) )
                        {
			question_user_last_big_string_id = k;
			setUnsaved();
			}
		}

        public PrimaryKey getAclId()
                {
                return acl_id;
                }

        public void setAclId( PrimaryKey key )
                {
                acl_id = key;
                setUnsaved();
                }

        /**
	 * Set all (up to 32) flags at once.  Mainly used by the Bodington
	 * system when loading the object from the database.  The setUnsaved()
	 * method is called if changes are made because this method might be
	 * used to modify an already instantiated object and the "unsaved"
	 * flag used later to conditionally save the object only if it is
	 * different to the database record it was loaded from.
	 * 
	 * @param f An integer representing up to 32 flags.
	 */
	public void setFlags( int f )
		{
		if ( f==flags ) return;
		flags=f;
    	setUnsaved();
		}


	public boolean isClosed()
		{
		return (flags & FLAG_CLOSED) != 0;
		}
	public void setClosed( boolean b )
		{
		if ( b == isClosed() )
			return;
		setFlags( flags ^ FLAG_CLOSED );
		}
		
   	/**
   	 * This static method is used to find and load LogBookPages from the database.  
   	 * Code that needs to find LogBookPages could call PersistentObject.findPersistentObject
   	 * directly but this method is a neater solution and provides an opportunity for
   	 * specialist initialisation for objects found.
   	 * 
   	 * @param key The primary key (id) of the LogBookPage to find and load.
   	 * @return Reference to the loaded LogBookPage or null if not found.
   	 * @exception org.bodington.server.BuildingServerException
   	 */
   	public static LogBookPage findLogBookPage( PrimaryKey key )
		throws BuildingServerException
		{
		return (LogBookPage)findPersistentObject( key, "org.bodington.logbook.server.LogBookPage" );
		}
	
   	/**
   	 * This static method is used to find and load LogBookPages from the database.  
   	 * Code that needs to find LogBookPages could call PersistentObject.findPersistentObject
   	 * directly but this method is a neater solution and provides an opportunity for
   	 * specialist initialisation for objects found.
   	 * 
   	 * @param where An SQL WHERE clause used to load a LogBookPage.
   	 * @return Reference to the loaded LogBookPage or null if not found.
   	 * @exception org.bodington.server.BuildingServerException
   	 */
   	public static LogBookPage findLogBookPage( String where )
		throws BuildingServerException
		{
		return (LogBookPage)findPersistentObject( where, "org.bodington.logbook.server.LogBookPage" );
		}

   	/**
   	 * This static method is used to find and load LogBookPages from the database.  
   	 * Code that needs to find LogBookPages could call PersistentObject.findPersistentObject
   	 * directly but this method is a neater solution and provides an opportunity for
   	 * specialist initialisation for objects found.
   	 * 
   	 * @param where An SQL WHERE clause used to load LogBookPages.
   	 * @return Reference to the loaded LogBookPage or null if not found.
   	 * @exception org.bodington.server.BuildingServerException
   	 */
   	public static Enumeration findLogBookPages( String where, String order )
		throws BuildingServerException
		{
		return findPersistentObjects( where, order, "org.bodington.logbook.server.LogBookPage" );
		}

        /**
	 * Utility method that loads the BigString object that
	 * is referenced by bigStringId.
	 * 
	 * @param bigStringId the ID of the big string to be returned.
	 * @return Text of the entry, or null if the ID is blank or not found.
	 * @exception org.bodington.server.BuildingServerException
	 */
	private String stringFromBigStringId( PrimaryKey bigStringId )
		throws BuildingServerException
		{
		if ( null == bigStringId )
			return null;
		BigString bstr = BigString.findBigString( bigStringId );
		if ( null == bstr )
			return null;
		return bstr.getString();
		}
		
	/**
	 * Utility method that finds the big string entry
	 * referenced by big_string_id and changes its text
	 * value.
	 * 
	 * @param bigStringId the ID of the big string to be updated, or null to create a new BigString.
	 * @param s The new text for this entry.
	 * @return the new or re-used existing identifier for this big string.
	 * @exception org.bodington.server.BuildingServerException
	 */
	private PrimaryKey insertOrUpdateBigString( PrimaryKey bigStringId, String s )
		throws BuildingServerException
		{
		BigString bstr=null;
		if ( null != bigStringId )
			bstr = BigString.findBigString( bigStringId );
		if ( null == bstr )
			{
			bstr = new BigString();
			}

		bstr.setString( s );
		bstr.save();
		return bstr.getBigStringId();
		}
	}
