/*
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.odftoolkit.simple.text;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.odftoolkit.odfdom.dom.OdfDocumentNamespace;
import org.odftoolkit.odfdom.dom.element.text.TextSectionElement;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.odftoolkit.odfdom.pkg.OdfFileDom;
import org.odftoolkit.simple.Component;
import org.odftoolkit.simple.Document;
import org.odftoolkit.simple.table.AbstractTableContainer;
import org.odftoolkit.simple.table.Table;
import org.odftoolkit.simple.table.Table.TableBuilder;
import org.odftoolkit.simple.table.TableContainer;
import org.odftoolkit.simple.text.list.AbstractListContainer;
import org.odftoolkit.simple.text.list.ListContainer;
import org.odftoolkit.simple.text.list.ListDecorator;
import org.w3c.dom.Node;
import sun.misc.BASE64Encoder;

/**
 * This class represents section definition in text document. It provides
 * methods to manipulate section in text document, such as getting/setting
 * section name, moving section and so on.
 *
 * @since 0.4
 */
public class Section extends Component implements ParagraphContainer,
		TableContainer, ListContainer {

	private ParagraphContainerImpl paragraphContainerImpl;
	private TableContainerImpl tableContainerImpl;
	private ListContainerImpl listContainerImpl;

	private TextSectionElement mSectionElement;
	private Document mDocument;
	private ProtectionKeyDigestProvider protectionKeyDigestProvider;

	private Section(Document doc, TextSectionElement element) {
		mSectionElement = element;
		mDocument = doc;
	}

	/**
	 * Get a section instance by an object of <code>TextSectionElement</code>.
	 *
	 * @param element
	 *            - an object of <code>TextSectionElement</code>
	 * @return an instance of <code>Section</code> that can represent
	 *         <code>TextSectionElement</code>
	 */
	public static Section getInstance(TextSectionElement element) {
		return new Section((Document) ((OdfFileDom) (element.getOwnerDocument())).getDocument(), element);
	}

	/**
	 * Return the ODF document which this section belongs to.
	 *
	 * @return - the ODF document which this section belongs to.
	 */
	public Document getOwnerDocument() {
		return mDocument;
	}

	/**
	 * Return the name of this section
	 *
	 * @return - the name of this section
	 */
	public String getName() {
		return mSectionElement.getTextNameAttribute();
	}

	/**
	 * Set the value of this section name
	 *
	 * @param name
	 *            - the value of name to be set
	 */
	public void setName(String name) {
		mSectionElement.setTextNameAttribute(name);
	}

	/**
	 * Remove this section from the document.
	 * <p>
	 * All the linked resources which are only linked to this section will be
	 * removed too.
	 *
	 */
	public void remove() {
		mDocument.removeElementLinkedResource(mSectionElement);
		mSectionElement.getParentNode().removeChild(mSectionElement);
		paragraphContainerImpl = null;
		mSectionElement = null;
		mDocument = null;
	}

	/**
	 * Return an instance of <code>TextSectionElement</code> which represents
	 * this section.
	 *
	 * @return - an instance of <code>TextSectionElement</code> which represents
	 *         this section
	 */
	public TextSectionElement getOdfElement() {
		return mSectionElement;
	}

	/**
	 * Return whether this section is contained in footer or header.
	 *
	 * @return - true if this section is contained in footer or header. false if
	 *         this section is not contained in footer or header.
	 */
	boolean isInHeaderFooter() {
		try {
			if (mSectionElement.getOwnerDocument() == mDocument.getStylesDom())
				return true;
		} catch (Exception e) {
			Logger.getLogger(Section.class.getName()).log(Level.SEVERE, "Failed in isInHeaderFooter", e);
		}
		return false;
	}

	/**
	 * Set the value to specify whether the section is protected.
	 * <p>
	 * If this value is set to false, the existing password will be removed at
	 * the same.
	 *
	 * @param isProtected
	 *            - "true" represents the section cannot be edited through a
	 *            user interface. "false" represents the section is allowed to
	 *            be edited.
	 */
	public void setProtected(boolean isProtected) {
		mSectionElement.setTextProtectedAttribute(isProtected);
		if (!isProtected && getProtectedPassword() != null)
			setProtectedWithPassword(null);
	}

	/**
	 * Return the value of section which specifies whether the section is
	 * protected.
	 *
	 * @return whether the section is protected.
	 */
	public boolean isProtected() {
		return mSectionElement.getTextProtectedAttribute();
	}

	/**
	 * Set the password which specifies that an authorization is required for
	 * removing the protection of this section.
	 * <p>
	 * If key is empty or null, the attribute of
	 * <code>text:protection-key</code> and
	 * <code>text:protection-key-digest-algorithm</code> will be removed.
	 * <p>
	 * The authentication procedure can be customized by
	 * {@link Section#setProtectionKeyDigestProvider(ProtectionKeyDigestProvider)}
	 * . The default digest algorighom of the protection key is SHA-1:
	 * {@link http://www.w3.org/2000/09/xmldsig#sha1.}
	 *
	 * @param key
	 *            -the value of the password.
	 *
	 */
	public void setProtectedWithPassword(String key) {
		if (key != null && key.length() > 0) {
			mSectionElement.setTextProtectionKeyAttribute(generateHashKey(key));
			mSectionElement
					.setTextProtectionKeyDigestAlgorithmAttribute(getDigestAlgorithm());
			setProtected(true);
		} else {
			mSectionElement.removeAttributeNS(OdfDocumentNamespace.TEXT
					.getUri(), "protection-key");
			mSectionElement.removeAttributeNS(OdfDocumentNamespace.TEXT
					.getUri(), "protection-key-digest-algorithm");
		}
	}

	/**
	 * Get the protection key of this section.
	 *
	 * @return the protection key of this section
	 */
	public String getProtectedPassword() {
		return mSectionElement.getTextProtectionKeyAttribute();
	}

	/**
	 * Get the protection key digest algorithm.
	 * <p>
	 * The default value is http://www.w3.org/2000/09/xmldsig#sha1, if no value
	 * specified.
	 *
	 * @return an IRI that identifies an authentication procedure for removing a
	 *         protection.
	 */
	public String getProtectionKeyDigestAlgorithm() {
		return mSectionElement.getTextProtectionKeyDigestAlgorithmAttribute();
	}

	private static class SHA1KeyDigest implements ProtectionKeyDigestProvider {

		private static final String KEY_DIGEST_ALGORITHM = "http://www.w3.org/2000/09/xmldsig#sha1";
		private static SHA1KeyDigest provider;

		static SHA1KeyDigest getInstance() {
			if (provider == null)
				provider = new SHA1KeyDigest();
			return provider;
		}

//		@Override
		public String generateHashKey(String passwd) {
			String hashKey = null;
			if (passwd != null && passwd.length() > 0) {
				MessageDigest md;
				try {
					byte[] pwd = new byte[passwd.length() * 2];
					for (int i = 0; i < passwd.length(); i++) {
						pwd[2 * i] = (byte) (passwd.charAt(i) & 0xFF);
						pwd[2 * i + 1] = (byte) (passwd.charAt(i) >> 8);
					}
					md = MessageDigest.getInstance("SHA-1");
					byte[] byteCode = md.digest(pwd);
					BASE64Encoder encoder = new BASE64Encoder();
					hashKey = encoder.encode(byteCode);
				} catch (NoSuchAlgorithmException e) {
					Logger.getLogger(Section.class.getName(),
							"Fail to initiate the digest method.");
				}
			}
			return hashKey;
		}

//		@Override
		public String getProtectionKeyDigestAlgorithm() {
			return KEY_DIGEST_ALGORITHM;
		}

	}

	/**
	 * Set the provider which provides corresponding protection key digest
	 * algorithm.
	 *
	 * @param provider
	 *            - an instance of a protection key digest algorithm provider
	 */
	public void setProtectionKeyDigestProvider(
			ProtectionKeyDigestProvider provider) {
		protectionKeyDigestProvider = provider;
	}

	/**
	 * Get current used provider which provides corresponding protection key
	 * digest algorithm.
	 *
	 * @return the current used provider.
	 */
	public ProtectionKeyDigestProvider getProtectionKeyDigestProvier() {
		if (protectionKeyDigestProvider == null) {
			protectionKeyDigestProvider = getDefaultProtectionKeyDigestProvider();
		}
		return protectionKeyDigestProvider;
	}

	/**
	 * Get the default provider which use SHA-1 standard as the protection key
	 * digest algorithm.
	 *
	 * @return the default protection key digest algorithm.
	 */
	public ProtectionKeyDigestProvider getDefaultProtectionKeyDigestProvider() {
		return SHA1KeyDigest.getInstance();
	}

	private String generateHashKey(String passwd) {
		return getProtectionKeyDigestProvier().generateHashKey(passwd);
	}

	private String getDigestAlgorithm() {
		return getProtectionKeyDigestProvier()
				.getProtectionKeyDigestAlgorithm();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Section))
			return false;
		Section aSection = (Section) obj;
		if (aSection == this)
			return true;
		return aSection.getOdfElement().equals(mSectionElement);
	}

	//****************Paragraph support******************//

	public Paragraph addParagraph(String textContent) {
		return getParagraphContainerImpl().addParagraph(textContent);
	}

	public OdfElement getParagraphContainerElement() {
		return getParagraphContainerImpl().getParagraphContainerElement();
	}

	public boolean removeParagraph(Paragraph para) {
		return getParagraphContainerImpl().removeParagraph(para);
	}

	private class ParagraphContainerImpl extends AbstractParagraphContainer {
		public OdfElement getParagraphContainerElement()
		{
			return mSectionElement;
		}
	}
	private ParagraphContainerImpl getParagraphContainerImpl() {
		if (paragraphContainerImpl == null)
			paragraphContainerImpl = new ParagraphContainerImpl();
		return paragraphContainerImpl;
	}

	public Paragraph getParagraphByIndex(int index, boolean isEmptyParagraphSkipped) {
		return getParagraphContainerImpl().getParagraphByIndex(index, isEmptyParagraphSkipped);
	}

	public Paragraph getParagraphByReverseIndex(int reverseIndex, boolean isEmptyParagraphSkipped) {
		return getParagraphContainerImpl().getParagraphByReverseIndex(reverseIndex, isEmptyParagraphSkipped);
	}

	public Iterator<Paragraph> getParagraphIterator() {
		return getParagraphContainerImpl().getParagraphIterator();
	}

	// ****************Table support******************//
	protected TableContainer getTableContainerImpl() {
		if (tableContainerImpl == null) {
			tableContainerImpl = new TableContainerImpl();
		}
		return tableContainerImpl;
	}

	private class TableContainerImpl extends AbstractTableContainer {

		public OdfElement getTableContainerElement() {
			return mSectionElement;
		}
	}

//	@Override
	public Table addTable() {
		return getTableContainerImpl().addTable();
	}

//	@Override
	public Table addTable(int numRows, int numCols) {
		return getTableContainerImpl().addTable(numRows, numCols);
	}

//	@Override
	public TableBuilder getTableBuilder() {
		return getTableContainerImpl().getTableBuilder();
	}

//	@Override
	public Table getTableByName(String name) {
		return getTableContainerImpl().getTableByName(name);
	}

//	@Override
	public OdfElement getTableContainerElement() {
		return getTableContainerImpl().getTableContainerElement();
	}

//	@Override
	public List<Table> getTableList() {
		return getTableContainerImpl().getTableList();
	}

	// ****************List support******************//

	private ListContainerImpl getListContainerImpl() {
		if (listContainerImpl == null) {
			listContainerImpl = new ListContainerImpl();
		}
		return listContainerImpl;
	}

	private class ListContainerImpl extends AbstractListContainer {

		public OdfElement getListContainerElement() {
			return mSectionElement;
		}
	}

//	@Override
	public org.odftoolkit.simple.text.list.List addList() {
		return getListContainerImpl().addList();
	}

//	@Override
	public org.odftoolkit.simple.text.list.List addList(ListDecorator decorator) {
		return getListContainerImpl().addList(decorator);
	}

//	@Override
	public void clearList() {
		getListContainerImpl().clearList();
	}

//	@Override
	public OdfElement getListContainerElement() {
		return getListContainerImpl().getListContainerElement();
	}

//	@Override
	public Iterator<org.odftoolkit.simple.text.list.List> getListIterator() {
		return getListContainerImpl().getListIterator();
	}

//	@Override
	public boolean removeList(org.odftoolkit.simple.text.list.List list) {
		return getListContainerImpl().removeList(list);
	}

    /**
     * Looks for an embedded section with a given name.
     *
     * @param chdSecName Section name looked for
     * @return TextSectionElement with the given name or null
     */
    public Section getEmbeddedSectionByName(String chdSecName) {
        OdfElement sectEle = getOdfElement();
        TextSectionElement sectChdEle = findChildSectionByName(sectEle, chdSecName);
        if (sectChdEle != null) {
            return new Section((Document) ((OdfFileDom) (sectEle.getOwnerDocument())).getDocument(), sectChdEle);
        } else {
            return null;
        }
    }

    /**
     * Recursive function. Looks for an TextSectionElement inside the father
     * Element 'ele' with the name sectionName
     *
     * @param ele
     * @param sectionName
     * @return TextSectionElement with the given name or null
     */
    private static TextSectionElement findChildSectionByName(OdfElement ele, String sectionName) {
        if (ele instanceof TextSectionElement) {
            // is ele the wanted Element?
            String name = ((TextSectionElement) ele).getTextNameAttribute();
            if (name != null) {
                if (name.equals(sectionName)) {
                    return (TextSectionElement) ele;
                }
            }
        }

        // this Element is not the wanted one? then examine all children
        Node chdNode = ele.getFirstChild();
        while (chdNode != null) {
            if (chdNode instanceof OdfElement) {
                TextSectionElement result = findChildSectionByName((OdfElement) chdNode, sectionName);
                if (result != null) {
                    return result;
                }
            }
            chdNode = chdNode.getNextSibling();
        }
        return null;
    }
}
