/* 
    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.wiki.tags;

import org.apache.log4j.Logger;
import org.apache.wiki.api.core.Context;
import org.apache.wiki.api.core.Page;

import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.TryCatchFinally;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;


/**
 *  Iterates through tags.
 *
 *  <P><B>Attributes</B></P>
 *  <UL>
 *    <LI>list - a collection.
 *  </UL>
 *
 *  @since 2.0
 */
public abstract class IteratorTag extends BodyTagSupport implements TryCatchFinally {

	private static final long serialVersionUID = 8945334759300595321L;
	protected String m_pageName;
    protected Iterator< ? > m_iterator;
    protected Context m_wikiContext;

    private static final Logger log = Logger.getLogger( IteratorTag.class );

    /**
     *  Sets the collection that is used to form the iteration.
     *  
     *  @param arg A Collection which will be iterated.
     */
    public void setList( final Collection< ? > arg ) {
        if( arg != null ) {
            m_iterator = arg.iterator();
        }
    }

    /**
     *  Sets the collection list, but using an array.
     *
     *  @param arg An array of objects which will be iterated.
     */
    public void setList( final Object[] arg ) {
        if( arg != null ) {
            m_iterator = Arrays.asList(arg).iterator();
        }
    }

    /**
     *  Clears the iterator away.  After calling this method doStartTag() will always return SKIP_BODY
     */
    public void clearList() {
        m_iterator = null;
    }
    
    /**
     *  Override this method to reset your own iterator.
     */
    public void resetIterator() {
        // No operation here
    }
    
    /** {@inheritDoc} */
    @Override
    public int doStartTag() {
        m_wikiContext = Context.findContext(pageContext);
        resetIterator();
        if( m_iterator == null ) {
            return SKIP_BODY;
        }
        if( m_iterator.hasNext() ) {
            buildContext();
        }

        return EVAL_BODY_BUFFERED;
    }

    /**
     *  Arg, I hate globals.
     */
    private void buildContext() {
        final Context context = m_wikiContext.clone();
        final Object o = m_iterator.next();
        if( o instanceof Page ) {
            context.setPage( ( Page )o );
        }

        pageContext.setAttribute( Context.ATTR_CONTEXT, context, PageContext.REQUEST_SCOPE );
        pageContext.setAttribute( getId(), o );
    }

    /** {@inheritDoc} */
    @Override
    public int doEndTag() {
        // Return back to the original.
        pageContext.setAttribute( Context.ATTR_CONTEXT, m_wikiContext, PageContext.REQUEST_SCOPE );

        return EVAL_PAGE;
    }

    /** {@inheritDoc} */
    @Override
    public int doAfterBody() {
        if( bodyContent != null ) {
            try {
                final JspWriter out = getPreviousOut();
                out.print( bodyContent.getString() );
                bodyContent.clearBody();
            } catch( final IOException e ) {
                log.error( "Unable to get inner tag text", e );
                // FIXME: throw something?
            }
        }

        if( m_iterator != null && m_iterator.hasNext() ) {
            buildContext();
            return EVAL_BODY_BUFFERED;
        }

        return SKIP_BODY;
    }
    
    /**
     *  In case your tag throws an exception at any point, you can override this method and implement a custom exception handler.
     *  <p>
     *  By default, this handler does nothing.
     *  
     *  @param arg0 The Throwable that the tag threw
     *  @throws Throwable I have no idea why this would throw anything
     */
    @Override
    public void doCatch( final Throwable arg0) throws Throwable {
    }

    /**
     *  Executed after the tag has been finished.  This is a great place to put any cleanup code.  However you <b>must</b> call
     *  super.doFinally() if you override this method, or else some of the things may not work as expected.
     */
    @Override
    public void doFinally() {
        resetIterator();
        m_iterator = null;
        m_pageName = null;
        m_wikiContext = null;        
    }

}
