package edu.vt.marian.Document;

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

import edu.vt.marian.common.*;


/**
    A "variable field" in a US MARC record that contains a subject:
	that is, a 6xx field.
    @author	Robert France

*/

public class MarcSubjectField extends PresentableMarcVarField
{
   /**
        Create a MarcSubjectField object with no subfields.
        @param	id -- the variable field id.
        @param	xMap -- used to convert ANSEL to (e.g.) XML.
        @param	debug -- used for debugging
    */      
    public MarcSubjectField(int id, EntityMap xMap, Debug debug)
    {
        super(id, xMap, debug);
        isSubject = true;
     }


    /**
        "Short" presentation for a subject variable field:  use 'a'
              subfields, separated with commas.
        @param	markupType    see edu.vt.marian.common.DigInfObj
        @param	out	A BufferedWriter (presumably String or OutputStream) to present on.
        @return    OK -- everything jake.
        <BR>    IO_ERROR or PARSE_ERROR -- problems.
    */      
    public int presentShort(int markupType, BufferedWriter out) throws IOException
    {
		int Err;
        switch ( markupType )
        {
         default:
            debug.dumpTrace("MarcSubjectField.presentShort(): Unexpected markup type " +
                            markupType + ":  treating as ASCII.");
            // Fall through:

         case DigInfObj.XML:
         case DigInfObj.SGML:
         case DigInfObj.HTML:
         case DigInfObj.ASCII:
         case DigInfObj.ANSEL:
            Enumeration subfld = subfields.elements();
            try { while ( true )
            {
                MarcSubField sf = (MarcSubField) subfld.nextElement();
                if ( sf.getLabel() == 'a' )
                   if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                if ( subfld.hasMoreElements() )
                   out.write(", ");
            } } catch( NoSuchElementException e) {};
        }
     return( ReturnCodes.OK );
    }


    /**
        "Long" presentation for a subject variable field.
        @param	markupType    see edu.vt.marian.common.DigInfObj
        @param	out	A BufferedWriter (presumably String or OutputStream) to present on.
        @return    OK -- everything jake.
        <BR>    IO_ERROR or PARSE_ERROR -- problems.
    */      
    public int presentLong(int markupType, BufferedWriter out) throws IOException 
    {
        Enumeration subfld = subfields.elements();
        boolean isFirstField = true;
        char lastLabel = '\0';
		int Err;
        switch ( markupType )
        {
         case DigInfObj.XML:	// Use default.
         case DigInfObj.SGML:
	        return( super.presentLong(markupType, out) );

         case DigInfObj.HTML:
            // Presentation:  make the full subject field a single hot link
            //  using the full indexed form of the individual subject entry
            //  as exact query text.

            // Build URL.
            StringWriter sw = new StringWriter();
            BufferedWriter bsw = new BufferedWriter( sw );
            if ( (Err = presentLong(DigInfObj.ANSEL, bsw)) != ReturnCodes.OK )
                return( Err );
			bsw.flush();
            String queryString = "text1_type=Exact Words in SubjEntry/text1=" +
                                    sw.toString();
            presentUrl(queryString, out);

            try { while ( true )
            {
                MarcSubField sf = (MarcSubField) subfld.nextElement();
                if (isFirstField)
                {
                    // this is the first sub field, don't need to add any 
                    // separator before it
                    isFirstField = false;
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                    lastLabel = sf.getLabel();
                }
                else if (sf.getLabel() == lastLabel)
                {
                    // this subfield and previous one are at same level
                    //  separate them by ','
                    out.write(", ");
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                }
                else
                {
                    // this subfield should be a subheading of the 
                    //  previous subfield, separate them by an N-dash.
                    out.write(" &#8212; ");
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                    lastLabel = sf.getLabel();
                }
            } } catch( NoSuchElementException e) {};

            out.write("</A>");
            return( ReturnCodes.OK );

         default:
            debug.dumpTrace("MarcSubjectField.presentLong(): Unexpected markup type " +
                            markupType + ":  treating as ASCII.");
            // Fall through:

         case DigInfObj.ASCII:
         case DigInfObj.ANSEL:
            try { while ( true )
            {
                MarcSubField sf = (MarcSubField) subfld.nextElement();
                if (isFirstField)
                {
                    // this is the first sub field, don't need to add any 
                    // separator before it
                    isFirstField = false;
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                    lastLabel = sf.getLabel();
                }
                else if (sf.getLabel() == lastLabel)
                {
                    // this subfield and previous one are at same level
                    //  separate them by ','
                    out.write(", ");
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                }
                else
                {
                    // this subfield should be a subheading of the 
                    //  previous subfield, separate them by " -- "
                    out.write(" -- ");
                    if ( (Err = sf.present(markupType, out)) != ReturnCodes.OK )
                        return( Err );
                    lastLabel = sf.getLabel();
                }
            } } catch( NoSuchElementException e) {};
            return( ReturnCodes.OK );
        }
    }

}

