/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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.apache.poi.hslf.record;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;

import org.apache.poi.hslf.exceptions.HSLFException;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianConsts;

/**
 * A UserEdit Atom (type 4085). Holds information which bits of the file
 *  were last used by powerpoint, the version of powerpoint last used etc.
 *
 * ** WARNING ** stores byte offsets from the start of the PPT stream to
 *  other records! If you change the size of any elements before one of
 *  these, you'll need to update the offsets!
 *
 * @author Nick Burch
 */

public final class UserEditAtom extends PositionDependentRecordAtom
{
	public static final int LAST_VIEW_NONE = 0;
	public static final int LAST_VIEW_SLIDE_VIEW = 1;
	public static final int LAST_VIEW_OUTLINE_VIEW = 2;
	public static final int LAST_VIEW_NOTES = 3;

	private byte[] _header;
	private static long _type = 4085l;
	private short unused;

	private int lastViewedSlideID;
	private int pptVersion;
	private int lastUserEditAtomOffset;
	private int persistPointersOffset;
	private int docPersistRef;
	private int maxPersistWritten;
	private short lastViewType;
	private int encryptSessionPersistIdRef = -1;

	// Somewhat user facing getters
	public int getLastViewedSlideID() { return lastViewedSlideID; }
	public short getLastViewType()    { return lastViewType; }

	// Scary internal getters
	public int getLastUserEditAtomOffset() { return lastUserEditAtomOffset; }
	public int getPersistPointersOffset()  { return persistPointersOffset; }
	public int getDocPersistRef()          { return docPersistRef; }
	public int getMaxPersistWritten()      { return maxPersistWritten; }
	public int getEncryptSessionPersistIdRef() { return encryptSessionPersistIdRef; }

	// More scary internal setters
	public void setLastUserEditAtomOffset(int offset) { lastUserEditAtomOffset = offset; }
	public void setPersistPointersOffset(int offset)  { persistPointersOffset = offset; }
	public void setLastViewType(short type)           { lastViewType=type; }
    public void setMaxPersistWritten(int max)         { maxPersistWritten=max; }
    public void setEncryptSessionPersistIdRef(int id) {
        encryptSessionPersistIdRef=id;
        LittleEndian.putInt(_header,4,(id == -1 ? 28 : 32));
    }

	/* *************** record code follows ********************** */

	/**
	 * For the UserEdit Atom
	 */
	protected UserEditAtom(byte[] source, int start, int len) {
		// Sanity Checking
		if(len < 34) { len = 34; }

		int offset = start;
		// Get the header
		_header = new byte[8];
		System.arraycopy(source,offset,_header,0,8);
		offset += 8;

		// Get the last viewed slide ID
		lastViewedSlideID = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Get the PPT version
		pptVersion = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Get the offset to the previous incremental save's UserEditAtom
		// This will be the byte offset on disk where the previous one
		//  starts, or 0 if this is the first one
		lastUserEditAtomOffset = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Get the offset to the persist pointers
		// This will be the byte offset on disk where the preceding
		//  PersistPtrFullBlock or PersistPtrIncrementalBlock starts
		persistPointersOffset = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Get the persist reference for the document persist object
		// Normally seems to be 1
		docPersistRef = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Maximum number of persist objects written
		maxPersistWritten = LittleEndian.getInt(source,offset);
		offset += LittleEndianConsts.INT_SIZE;

		// Last view type
		lastViewType = LittleEndian.getShort(source,offset);
		offset += LittleEndianConsts.SHORT_SIZE;
		
		// unused
		unused = LittleEndian.getShort(source,offset);
		offset += LittleEndianConsts.SHORT_SIZE;

		// There might be a few more bytes, which are a reserved field
		if (offset-start<len) {
		    encryptSessionPersistIdRef = LittleEndian.getInt(source,offset);
		    offset += LittleEndianConsts.INT_SIZE;
		}
		
		assert(offset-start == len);
	}

	/**
	 * We are of type 4085
	 */
	@Override
    public long getRecordType() { return _type; }

	/**
	 * At write-out time, update the references to PersistPtrs and
	 *  other UserEditAtoms to point to their new positions
	 */
	@Override
    public void updateOtherRecordReferences(Map<Integer,Integer> oldToNewReferencesLookup) {
		// Look up the new positions of our preceding UserEditAtomOffset
		if(lastUserEditAtomOffset != 0) {
			Integer newLocation = oldToNewReferencesLookup.get(Integer.valueOf(lastUserEditAtomOffset));
			if(newLocation == null) {
				throw new HSLFException("Couldn't find the new location of the UserEditAtom that used to be at " + lastUserEditAtomOffset);
			}
			lastUserEditAtomOffset = newLocation.intValue();
		}

		// Ditto for our PersistPtr
		Integer newLocation = oldToNewReferencesLookup.get(Integer.valueOf(persistPointersOffset));
		if(newLocation == null) {
			throw new HSLFException("Couldn't find the new location of the PersistPtr that used to be at " + persistPointersOffset);
		}
		persistPointersOffset = newLocation.intValue();
	}

	/**
	 * Write the contents of the record back, so it can be written
	 *  to disk
	 */
	@Override
    public void writeOut(OutputStream out) throws IOException {
		// Header
		out.write(_header);

		// Write out the values
		writeLittleEndian(lastViewedSlideID,out);
		writeLittleEndian(pptVersion,out);
		writeLittleEndian(lastUserEditAtomOffset,out);
		writeLittleEndian(persistPointersOffset,out);
		writeLittleEndian(docPersistRef,out);
		writeLittleEndian(maxPersistWritten,out);
		writeLittleEndian(lastViewType,out);
		writeLittleEndian(unused,out);
		if (encryptSessionPersistIdRef != -1) {
		    // optional field
		    writeLittleEndian(encryptSessionPersistIdRef,out);
		}
	}
}
