/* ======================================================================
   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.servlet.template;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.servlet.ServletException;

import org.bodington.servlet.FacilityList;
import org.bodington.servlet.Request;
import org.bodington.servlet.facilities.Facility;

/**
 * The base Template class that all compiled templates extend.
 * When a template is compiled it extends this class or one of its
 * subclasses.
 * @author  bmb6jrm
 */
public abstract class XmlTemplateProcessor
{
    
    /** Creates new XmlTemplateProcessor */
    public XmlTemplateProcessor()
    {
    }
    
    /**
     * The main entry point for running a compiled template.
     * The compiled templates must implement this method.
     */
    public abstract void process(org.bodington.servlet.Request request, org.bodington.servlet.Response response)
    throws java.io.IOException, javax.servlet.ServletException;

    /**
     * The method insertInteractive. <p>
     * <i>(WebLearn modification: May 2004 Colin Tatham <br />
     * Modified method to set and read insert attributes.
     * (allows building commands to name which Facility class to use:
     * i.e. &lt;building facility=suite command=hullo&gt; )</i>
     * @param writer The PrintWriter to send the output to, will be <code>null</code>
     * if in a block that isn't being executed.
     */
    protected void insertInteractive(org.bodington.servlet.Request request, java.io.PrintWriter writer, java.util.Map attributes) throws java.io.IOException, javax.servlet.ServletException
    {
    //      Facility facility = request.getFacility();
    //      request.setInsertAttributes( attributes );
    
          /* @todo change code on line 106 below? (imgtplate = Template.get( request.getFacility() ? */
          Facility facility;
          String att;
    	
    	request.setInsertAttributes( attributes );
          att = request.getInsertAttribute( "facility", null );
    
          if ( att != null )
          {
            FacilityList fl = FacilityList.getFacilities();
            facility = fl.get( att );
          }
          else
            facility = request.getFacility();
    	
    	if ( request.getInsertCommand()==null )
    	{
    	    writer.println( "<! invalid BUILDING tag>" );
    	    return;
    	}
    	
    	try
    	{
    	    facility.insert( request, writer, request.getInsertCommand(), request.getInsertName() );
    	}
    	catch ( RuntimeException runex )
    	{
    	    facility.logException( writer, "BuildingServlet", "insertInteractive",
    	    "Technical error trying to insert iteractive item.",
    	    runex );
    	}
    	
        }
    
    /**
     * Convert a 2D array into a Map. This method is needed so that
     * we can create a Map statically in a template.
     * @param array A 2D array with two columns.
     * @return A map with the key being the first column and the value being the second.
     */
    public static Map arrayToMap(String[][] array)
    {
        Map map = new HashMap();
        for (int row = 0; row < array.length; row++)
        {
            try
            {
                map.put(array[row][0], array[row][1]);
            }
            catch (IndexOutOfBoundsException ioobe)
            {
                // Should we log this?
            }
        }
        return map;
    }
}
