//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.publishing.services.index;

import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Hashtable;
import java.util.Vector;

import com.ibm.icu.util.StringTokenizer;

//Object holding definitionfile information
public class DefinitionObject
{
  private String indextitle = "Index - Basic Unified Process"; //$NON-NLS-1$
  private String see = ", See "; //$NON-NLS-1$
  private String seealso  = ", See also "; //$NON-NLS-1$
  private String characterset = "utf-8";
  public String keyWordSeparator = "|"; //$NON-NLS-1$
  public String levelSeparatorReplace = ":"; //$NON-NLS-1$
  String wwwRoot = null;
  int stipLength=0;
  String relativepath = null;
  String target=null;
  String specKeyWordFile=null;
  String mainResultFile=null;
  String indexResultFile=null;
  String indexTarget=null;
  String indexHeight=null;
  String keywordTarget=null;
  String keywordResultFile=null;
  String headerFile=null;
  String footerFile=null;
  String keyWordPrefix=Def.DefaultKeyWordPrefix;
  String keyWordLevelSeparator=Def.DefaultKeyWordLevelSeparator;

  boolean multidocumentkeyword=false;
  boolean showdocumenttitle=false;
  Vector stopDirsV=null;
   Hashtable fontDefinitions=null;
  Hashtable styleDefinitions=null;

  private File defFileRoot;

  //Constructor that parses the definitionfile
  public DefinitionObject(String pubDir, String deffile, String charSet)
  {
	  setwwwRoot(pubDir);
	  defFileRoot = new File(deffile).getParentFile();

     // Read the definition file and split the deffile into it's individual lines.
	String infile = MiscStatic.loadFile(deffile,charSet);
    StringTokenizer parser = new StringTokenizer(infile, "\t\n"); //$NON-NLS-1$

     stopDirsV = new Vector();
     fontDefinitions = new Hashtable(10);
     styleDefinitions = new Hashtable(10);
     while(parser.hasMoreTokens())
     {
        String param = parser.nextToken().trim();

        if(param.equalsIgnoreCase(Def.LevelFont))
        {
           asignFont(parser);
        }
        else if(param.equalsIgnoreCase(Def.LevelStyle))
        {
           asignStyle(parser);
        }      
        else
        {
           String value = parser.nextToken().trim();
           if(value==null)
           {
             System.err.println("DefinitionObject:addValue\n" + //$NON-NLS-1$
                      HelpMessages.PARAMETER_MISSING_VALUE + param);
             return;
           }
           asignValue(param, value);
        }
     }

  }

  //Check if enough input is read
  public boolean enoughInput()
  {
     boolean enough=true;
     StringBuffer buff = new StringBuffer();
     buff.append("\n"); //$NON-NLS-1$
     if(wwwRoot==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.WWWRootParam);
        enough=false;
     }

     if(keywordResultFile==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.KeyWordResultFile);
        enough=false;
     }

     if(indexResultFile!=null && mainResultFile==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.MainResultFile);
        enough=false;
     }

     if(indexResultFile!=null && indexTarget==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.IndexTarget);
        enough=false;
     }

     if(indexResultFile!=null && keywordTarget==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.KeyWordTarget);
        enough=false;
     }

     if(indexResultFile!=null && indexHeight==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.IndexHeight);
        enough=false;
     }

     if(relativepath==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.RelPath);
        enough=false;
     }

     if(headerFile==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.HeaderFile);
        enough=false;
     }

     if(footerFile==null)
     {
        buff.append(HelpMessages.PARAMETER_MISSING + Def.FooterFile);
        enough=false;
     }

     FontObject f = (FontObject)fontDefinitions.get(Def.DefaultFont);
     FontObject fs = (FontObject)styleDefinitions.get(Def.DefaultStyle);
     if(f==null && fs==null)
     {
        buff.append(HelpMessages.FONT_AND_STYLE_MISSING + Def.DefaultFont + " " + Def.DefaultStyle); //$NON-NLS-1$
        enough=false;
     }
     if(!enough)
     {
        buff.append("\n"); //$NON-NLS-1$
        System.err.println(buff);
     }
     return enough;
  }


  //Asigns values to the different attributes
  private void asignValue(String param, String value)
  {

    if(param.equalsIgnoreCase(Def.MainResultFile))
    {
       mainResultFile = value;
    }
    else if(param.equalsIgnoreCase(Def.CharacterSet))
    {
       characterset = value;
    }
    else if(param.equalsIgnoreCase(Def.See))
    {
       see = value;
    }
    else if(param.equalsIgnoreCase(Def.SeeAlso))
    {
       seealso = value;
    }
    else if(param.equalsIgnoreCase(Def.IndexResultFile))
    {
       indexResultFile = value;
    }
    else if(param.equalsIgnoreCase(Def.KeyWordResultFile))
    {
       keywordResultFile = value;
    }
    else if(param.equalsIgnoreCase(Def.HeaderFile))
    {
       headerFile = new File(defFileRoot, value).getAbsolutePath();;
    }
    else if(param.equalsIgnoreCase(Def.FooterFile))
    {
       footerFile = new File(defFileRoot, value).getAbsolutePath();;
    }
    else if(param.equalsIgnoreCase(Def.RelPath))
    {
       relativepath = value;
    }
    else if(param.equalsIgnoreCase(Def.DefaultTargetParam))
    {
       target = value;
    }
    else if(param.equalsIgnoreCase(Def.KeyWordFile))
    {
       specKeyWordFile = new File(defFileRoot, value).getAbsolutePath();
    }
    else if(param.equalsIgnoreCase(Def.IndexTitle))
    {
       indextitle = value;
    }
    else if(param.equalsIgnoreCase(Def.KeyWordTarget))
    {
       keywordTarget = value;
    }
    else if(param.equalsIgnoreCase(Def.IndexTarget))
    {
       indexTarget = value;
    }
    else if(param.equalsIgnoreCase(Def.IndexHeight))
    {
       indexHeight = value;
    }
    else if(param.equalsIgnoreCase(Def.MultiDocKeyWord))
    {
       multidocumentkeyword = value.equalsIgnoreCase(Def.True);
    }
    else if(param.equalsIgnoreCase(Def.ShowDocTitle))
    {
       showdocumenttitle = value.equalsIgnoreCase(Def.True);
    }
    else if(param.equalsIgnoreCase(Def.LeaveDir))
    {
       stopDirsV.addElement(value);
    }
      else if(param.equalsIgnoreCase(Def.KeyWordPrefix))
    {
       keyWordPrefix = value;
    }
    else if(param.equalsIgnoreCase(Def.KeyWordLevelSeparator))
    {
       keyWordLevelSeparator = value;
    }
    else
    {

       System.err.println(HelpMessages.INVALID_PARAMETER_NAME + param);
    }

  }

  //Parses a fontdefinition
  private void asignFont(StringTokenizer parser)
  {
    String stringLevel = parser.nextToken().trim();
    Object key = stringLevel;
    if(!stringLevel.equalsIgnoreCase(Def.DefaultFont) && !stringLevel.equalsIgnoreCase(Def.HeadLineFont))
    {
       key =  new Integer(stringLevel);
    }
    String name = parser.nextToken().trim();
    String style = parser.nextToken().trim();
    String size = parser.nextToken().trim();

    fontDefinitions.put(key,new FontObject(name, style, size));
  }

  //Parses a styledefinition
  private void asignStyle(StringTokenizer parser)
  {
    String stringLevel = parser.nextToken().trim();
    Object key = stringLevel;
    if(!stringLevel.equalsIgnoreCase(Def.DefaultStyle) && !stringLevel.equalsIgnoreCase(Def.HeadLineStyle))
    {
       key =  new Integer(stringLevel);
    }

    String style = parser.nextToken().trim();
    styleDefinitions.put(key,new FontObject(style));
  }
  
  //Check if the reached directory is whithin the stopdirlist
   public  boolean isInStopdir(String str)
   {
      for(int i=0;i<stopDirsV.size();i++)
      {
         String tmpStr = (String) stopDirsV.elementAt(i);
         if(str.substring(KeyWordIndexHelper.defObj.getWwwRoot().length()+1).compareTo(tmpStr)==0)
         {
            return true;
         }
      }
      return false;
  }

  //Accessmethods
  public String getIndexTitle()
  {
    return indextitle;
  }

  public String getSee()
  {
    return see;
  }

  public String getSeeAlso()
  {
    return seealso;
  }

  public String getCharacterSet()
  {
    return characterset;
  }
  public boolean getMulitDocumentKeyword()
  {
    return multidocumentkeyword;
  }

  public boolean getShowDocumentTitle()
  {
    return showdocumenttitle;
  }

  public String getKeyWordTarget()
  {
    return keywordTarget;
  }

  public String getIndexTarget()
  {
    return indexTarget;
  }

  public String getIndexHeight()
  {
    return indexHeight;
  }

  public String getWwwRoot()
  {
    return wwwRoot;
  }

  public int getWwwRootLength()
  {
    return stipLength;
  }

  public String getTarget()
  {
    return target;
  }

  public String getKeyWordFile()
  {
    return specKeyWordFile;
  }

  public String getMainResultFile()
  {
    return mainResultFile;
  }

  public String getIndexResultFile()
  {
    return indexResultFile;
  }

  public String getKeywordResultFile()
  {
    return keywordResultFile;
  }


  public String getRelativePath()
  {
    return relativepath;
  }

  public String getHeaderFile()
  {
    return headerFile;
  }

   public String getFooterFile()
  {
    return footerFile;
  }

 public String getKeyWordPrefix()
 {
   return keyWordPrefix;
 }

 public String getKeyWordLevelSeparator()
 {
   return keyWordLevelSeparator;
 }

 public FontObject getFont(int level)
  {
     FontObject f = (FontObject)fontDefinitions.get(new Integer(level));
     if(f==null)
     {
        f = (FontObject)fontDefinitions.get(Def.DefaultFont);
     }
     return f;
  }

  public FontObject getFont(Object key)
  {
     return (FontObject)fontDefinitions.get(key);

  }

  public FontObject getStyleSheet(int level)
  {
     FontObject f = (FontObject)styleDefinitions.get(new Integer(level));
     if(f==null)
     {
        f = (FontObject)styleDefinitions.get(Def.DefaultStyle);
     }
     return f;
  }

  public FontObject getStyleSheet(Object key)
  {
    return (FontObject)styleDefinitions.get(key);
  }

  public void printStart(OutputStreamWriter outP,int level)
  {
    if(getStyleSheet(Def.DefaultStyle)==null)
    {
      FontObject f = getFont(level);
      if(f==null)
      {
        f = getFont(Def.DefaultFont);
      }
      printStart(outP, f);
    }
    else
    {
        FontObject f = getStyleSheet(level);
        if(f==null)
        {
           f = getStyleSheet(Def.DefaultStyle);
        }
        printStart(outP, f);
    }
  }
  public void printStart(OutputStreamWriter outP,FontObject f)
  {

    if(outP==null)
    {
        System.out.println("DefinitionObject:printStart\n" + HelpMessages.BAD_OUTPUT_STREAM); //$NON-NLS-1$
        return;
    }


    if(f!=null && f.getStyleSheet()==null)
    {
      MiscStatic.print(outP,"<FONT FACE=\"" + f.getName() + "\" SIZE=\"" + f.getSize() + "\" >\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
      if(f.isItalic())
      {
        MiscStatic.print(outP,"<I>"); //$NON-NLS-1$
      }

      if(f.isBold())
      {
        MiscStatic.print(outP,"<B>"); //$NON-NLS-1$
      }
    }
    else
    {
        MiscStatic.print(outP, "<P CLASS=\"" + f.getStyleSheet() + "\">\n"); //$NON-NLS-1$ //$NON-NLS-2$
    }
  }

  public void printEnd(OutputStreamWriter outP, int level)
  {

    if(outP==null)
    {
        System.out.println("DefinitionObject:printEnd\n" + HelpMessages.BAD_OUTPUT_STREAM); //$NON-NLS-1$
        return;
    }

    if(getStyleSheet(Def.DefaultStyle)==null)
    {
      FontObject f = getFont(level);
      if(f==null)
      {
        f = getFont(Def.DefaultFont);
      }
      printEnd(outP, f);
    }
    else
    {
        printEnd(outP, null);
    }
  }

  public void printEnd(OutputStreamWriter outP, FontObject f)
  {
        if(outP==null)
    {
        System.out.println("DefinitionObject:printEnd\n" + HelpMessages.BAD_OUTPUT_STREAM); //$NON-NLS-1$
        return;
    }

    if(f!=null && f.getStyleSheet()==null)
    {
      if(f.isBold())
      {
        MiscStatic.print(outP,"</B>"); //$NON-NLS-1$
      }

      if(f.isItalic())
      {
        MiscStatic.print(outP,"</I>"); //$NON-NLS-1$
      }
      MiscStatic.print(outP,"</FONT>\n"); //$NON-NLS-1$
    }
    else
    {
        MiscStatic.print(outP,"</P>\n"); //$NON-NLS-1$
    }
  }
  //---------------------------------------------------------------------------------------------
  //
  //	RPW 2.0 Integration -- Do not modify this code unless you know what you are doing.
  //	  //	Because RPW calls these applications from a different location than the batch file
  //	it is neccessary to override the defaults in the config file.
  //
  //	The following methods simply allow the values to be over-ridden.
  //
  //----------------------------------------------------------------------------------------------
  public void setwwwRoot(String newRoot)
  {
      try {
		File wwwDir = new File(newRoot);
		wwwRoot = wwwDir.getCanonicalPath() + "/"; //$NON-NLS-1$
		wwwRoot = wwwRoot.replace('\\' , '/');
		stipLength = wwwRoot.length()-1;
	} catch (IOException e) {
		e.printStackTrace();
	}
  }

  public void setRelativePath(String newPath)
  {
	relativepath = newPath;
  }
  
  public void setIndexTitle(String title)
  {
	  indextitle = title;
  }  
}