/* ======================================================================
   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.server.ims;

import org.apache.log4j.Logger;

import java.io.*;
import java.util.*;

public class ImsPackageItem extends java.util.Vector
    {
    
    private static Logger log = Logger.getLogger(ImsPackageItem.class);
    
    public final static int ORGANIZATIONS=0;
    public final static int ORGANIZATION=1;
    public final static int ITEM=2;

    private int type;
    
    private String identifier;
    private String resourceref;
    private String title;
    
    private String def;
    private ImsPackageItem deforg;
    
    public ImsPackageItem( int type, String identifier, String resourceref, String title )
        {
        if ( type<0 || type >2 )
            throw new ArrayIndexOutOfBoundsException( "Invalid type." );
            
        switch ( type )
            {
            case ORGANIZATIONS:
                if ( identifier != null || title != null || resourceref!=null )
                    throw new NullPointerException( "An organizations must not have an identifier, a resourceref or a title." );
                break;
            case ORGANIZATION:
                if ( identifier == null )
                    throw new NullPointerException( "An organization must have an identifier." );
                if ( resourceref!=null )
                    throw new NullPointerException( "An organizastion must not have a resourceref." );
                break;
            case ITEM:
                if ( identifier == null || title == null )
                    throw new NullPointerException( "An item must have an identifier and a title." );
                break;
            }
            
        this.type = type;
        this.identifier = identifier;
        this.resourceref = resourceref;
        this.title = title;
        def=null;
        deforg=null;
        }
    
    
    public int getType() { return type; }
    public String getIdentifier() { return identifier; }
    public String getResourceref() { return resourceref; }
    public String getTitle() { return title; }
    public void setTitle( String title )
        { 
        if ( title == null )
            throw new NullPointerException( "Null title is not allowed." );
        this.title = title;
        }
        
    public String getDefault() { return def; }
    public void setDefault( String def )
        { 
        if ( def == null )
            throw new NullPointerException( "Null default is not allowed." );
        this.def = def;
        }
        
    public ImsPackageItem getDefaultOrganization() { return deforg; }
    public void setDefaultOrganization( ImsPackageItem deforg )
        { 
        this.deforg = deforg;
        }
        
    public void appendItem( ImsPackageItem item )
        {
        if ( item.getType() == ORGANIZATIONS )
            throw new IllegalArgumentException( "Can't add an orgnizations element to an item." );
        if ( item.getType() == ORGANIZATION && this.getType() != ORGANIZATIONS )
            throw new IllegalArgumentException( "The organization element can only be added to an orgnizations element." );
        if ( item.getType() == ITEM && this.getType() != ORGANIZATION  && this.getType() != ITEM)
            throw new IllegalArgumentException( "The item element can only be added to an orgnization element or another item element." );
            
        if ( item.getType() == ORGANIZATION && deforg == null )
      		deforg = item;

        this.addElement( item );
        }
        
    public void printHtml( PrintWriter out, Hashtable resources )
        {
        printHtml( out, resources, 1 );
        }
        
    private void printHtml( PrintWriter out, Hashtable resources, int level )
        {
        String href;
        
        if ( type == ORGANIZATIONS )
            {
            out.print( "<HTML><BODY><H" );
            out.print( level );
            out.print( ">Experimental output of IMS Package organizations</H" );
            out.print( level );
            out.println( ">" );
            }
        else if  ( type == ORGANIZATION )
            {
            out.print( "<H" );
            out.print( level );
            out.print( ">" );
            out.print( title );
            out.print( "</H" );
            out.print( level );
            out.println( ">" );
            }
        else
            {
            href=null;
            if ( resourceref!=null )
                href = (String)resources.get( resourceref );

            out.print( "<H" );
            out.print( level );
            out.print( ">" );
            if ( href!=null )
                {
                out.print( "<A HREF=\"" );
                out.print( href );
                out.print( "\">" );
                }
            out.print( title );
            if ( href!=null )
                out.print( "</A>" );
            out.print( "</H" );
            out.print( level );
            out.println( ">" );
            }
     
        ImsPackageItem child;
        boolean deforgdone=false;
        
        if ( type == ORGANIZATIONS && deforg!=null )
            {
            deforg.printHtml( out, resources, level+1 );
            deforgdone=true;
            
            if ( this.size() > 1 )
                {
                out.println( "<H1>Alternate organizations of content</H1>" );
                }
            }
            
        for ( int i=0; i<this.size(); i++ )
            {
            child = (ImsPackageItem)this.elementAt( i );

            //skip an organization if it is the default and
            //has already been output

            if ( deforgdone && child == deforg )
                continue;
            child.printHtml( out, resources, level+1 );
            }

        if ( type == ORGANIZATIONS )
            out.println( "</PRE></BODY></HTML>" );
        }

    public void printMenuXML( PrintWriter out, Hashtable resources )
        {
        out.println( "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" );
        out.println( "<menu automatic=\"true\">" );

        if ( deforg == null )
      		printHtml( out, resources, 1 );
        else
      		deforg.printMenuXML( out, resources, 1 );

        out.println( "</menu>" );
        }
        
    private void printMenuXML( PrintWriter out, Hashtable resources, int level )
        {
        String href;
        
        log.debug( "Another node for menu, resourceref = " + resourceref );
        
        if  ( type != ORGANIZATION || level>1 )
            {
            href=null;
            if ( resourceref!=null )
                href = (String)resources.get( resourceref );

      		log.debug( "Another node for menu, href = " + href );

            out.print( "<item" );
            if ( this.size()>0 || href==null )
            	out.print( " type=\"container\"" );
            else
            	out.print( " type=\"file\"" );
            if ( href!=null )
                {
                out.print( " href=\"" );
                out.print( href );
                out.print( "\"" );
                }
            out.println( ">" );
            out.print( "<title>" );
            if ( title!=null )
            	out.print( title );
            else
            	out.print( "untitled item" );
            out.println( "</title>" );
            }

        ImsPackageItem child;

   		for ( int i=0; i<this.size(); i++ )
      		{
      		child = (ImsPackageItem)this.elementAt( i );
      		child.printMenuXML( out, resources, level+1 );
      		}

        if  ( type != ORGANIZATION || level>1 )
            out.println( "</item>" );
        }

    }
