package org.plenix.jsp;

import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Hashtable;
import java.util.StringTokenizer;

public class Util
{
  // File methods
  public static String getFileContents(String fileName)
    throws IOException
  {
    FileInputStream inputStream = new FileInputStream(fileName);
    return getFileContents(inputStream);
  }

  public static String getFileContents(InputStream input)
    throws IOException
  {
    InputStreamReader reader = new InputStreamReader(input);

    int len;
    char chr[] = new char[4096]; // Big enough chunk
    StringBuffer buffer = new StringBuffer();

    while ((len = reader.read(chr)) > 0)
    {
      buffer.append(chr, 0, len);
    }

    return buffer.toString();
  }

  // String methods
  public static String getDirectoryName(String fileName)
  {
    return fileName.substring(0, fileName.lastIndexOf(File.separator));
  }

  public static String getNormalizedName(String fileName)
  {
    StringBuffer buffer = new StringBuffer();
    fileName = fileName.substring(0, fileName.lastIndexOf("."));

    String[] path = split(fileName, File.separator);

    for (int i = path[0].length() == 0 ? 1 : 0; i < path.length; i++)
    {
      if (i > 0)
      {
        buffer.append(File.separator);
      }

      buffer.append('_');
      char[] chars = path[i].toCharArray();

      for (int j = 0; j < chars.length; j++)
      {
        if (isAlphaNumeric(chars[j]))
        {
          buffer.append(chars[j]);
        }
        else
        {
          buffer.append('_');
        }
      }
    }

    return buffer.toString();
  }

  public static boolean isAlphaNumeric(char c)
  {
    return c == '_' ||
           (c >= 'a' && c <= 'z') ||
           (c >= 'A' && c <= 'Z') ||
           (c >= '0' && c <= '9');
  }

  public static String htmlEncode(String text)
  {
    int length = text.length();
    StringBuffer buffer = new StringBuffer();

    for (int i = 0; i < length; i++)
    {
      char c = text.charAt(i);

      switch (c)
      {
        case '&':
          buffer.append("&amp;");
          break;
        case '<':
          buffer.append("&lt;");
          break;
        case '>':
          buffer.append("&gt;");
          break;
        default:
          buffer.append(c);
          break;
      }
    }

    return buffer.toString();
  }

  public static String stringEncode(String text)
  {
    char chr[] = text.toCharArray();
    StringBuffer buffer = new StringBuffer();

    for (int i = 0; i < chr.length; i++)
    {
      switch (chr[i])
      {
        case '\r':
          buffer.append("\\r");
          break;
        case '\n':
          buffer.append("\\n");
          break;
        case '\t':
          buffer.append("\\t");
          break;
        case '"':
        case '\'':
          buffer.append('\\');
          // Fall through
        default:
          buffer.append(chr[i]);
          break;
      }
    }

    return buffer.toString();
  }

  public static String unquote(String text)
  {
    if (text.startsWith("'") || text.startsWith("\""))
      text = text.substring(1, text.length() - 1);

    return text;
  }

  public static String parseForVars(String string, String[] environment)
  {
    Hashtable variables = new Hashtable();

    for (int i = 0; i < environment.length; i++)
    {
      StringTokenizer tokenizer = new StringTokenizer(environment[i], "=");

      variables.put(tokenizer.nextToken(), tokenizer.nextToken());
    }

    return parseForVars(string, variables);
  }

  public static String parseForVars(String string, Hashtable variables)
  {
    if (string == null)
    {
      return null;
    }

    String returnValue = "";

    int c;
    int i = 0;

    while (i < string.length())
    {
      if ((c = string.charAt(i)) == '$')
      {
        if (i < (string.length() - 1)) // Skip $
        {
          i++;
        }

        if (string.charAt(i) == '\\') // False alarm
        {
          returnValue += "$";
          i++;
        }
        else
        {
          int j = findNextNonIdentifier(string, i);
          String variableName = string.substring(i, j);

          if (variables.containsKey(variableName))
          {
            returnValue += (String) variables.get(variableName);
            i = j;
          }
          else
          {
            returnValue += "$";
            i++;
          }
        }
      }
      else
      {
        returnValue += string.substring(i, i + 1);
        i++;
      }
    }

    return returnValue;
  }

  public static int findNextNonIdentifier(String string, int position)
  {
    int i;
    int length = string.length();

    for (i = position; i < length; i++)
    {
      char c = string.charAt(i);

      if (!(
        c == '_' ||
        c == '.' ||
        (c >= 'a' && c <= 'z') ||
        (c >= 'A' && c <= 'Z') ||
        ((i > position) && (c >= '0' && c <= '9'))
      ))
        break;
    }

    return i;
  }

  public static String[] split(String line)
  {
    return split(line, " \t\r\n");
  }

  public static String[] split(String line, String delimiter)
  {
    StringTokenizer tokenizer = new StringTokenizer(line, delimiter);
    int tokenCount = tokenizer.countTokens();
    String[] result = new String[tokenCount];

    for (int i = 0; i < tokenCount; i++)
    {
      result[i] = tokenizer.nextToken();
    }

    return result;
  }

  public static String escapeQuote(String theString)
  {
    return escape(theString, "'");
  }

  public static String escapeDoubleQuote(String theString)
  {
    return escape(theString, "\"");
  }

  public static String escape(String theString, String theChars)
  {
    return escape(theString, theChars, '\\');
  }

  public static String escape(String theString, String theChars, char theEscapeChar)
  {
    char[] chars = theChars.toCharArray();
    char[] string = theString.toCharArray();
    StringBuffer buffer = new StringBuffer();

    for (int i = 0; i < string.length; i++)
    {
      for (int j = 0; j < chars.length; j++)
      {
        if (string[i] == chars[j])
        {
          buffer.append(theEscapeChar);
          break;
        }
      }

      buffer.append(string[i]);
    }

    return buffer.toString();
  }
}
