/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   All rights reserved                                                    **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the Eclipse Public License 1.0 which accompanies this     **
 **   distribution, and is available at:                                     **
 **   http://www.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.util.shop;

import java.util.Vector;

/**
 * Class provides some methods to handle / work with Strings.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class StringShop {

  /** Custom Tokenizer for Authentication Strings */
  public static final String AUTH_TOKENIZER = " =;;= ";

  /** Custom Tokenizer for Category Path */
  public static final String CAT_TOKENIZER = "=;=";

  /** Data used for empty DND Text Transfers */
  public static final String EMPTY_TEXT_DATA = " ";

  /** This utility class constructor is hidden */
  private StringShop() {
  // Protect default constructor
  }

  /**
   * Create a HTML anchor from the given URL.
   * 
   * @param url The URL of the new anchor
   * @return String A HTML anchor
   */
  public static String createAnchor(String url) {
    return createAnchor(url, url);
  }

  /**
   * Create a HTML anchor from the given URL.
   * 
   * @param url The URL of the new anchor
   * @param name The Name of the new anchor
   * @return String A HTML anchor
   */
  public static String createAnchor(String url, String name) {
    StringBuffer strBuf = new StringBuffer();
    strBuf.append("<a href=\"").append(url).append("\">").append(name).append("</a>");
    return strBuf.toString();
  }

  /**
   * Create a valid filename from the given String.
   * 
   * @param str The String to convert to a valid filename.
   * @return String A valid filename.
   */
  public static String createFileName(String str) {

    /** Replace some special chars */
    str = str.replaceAll(" \\| ", "_");
    str = str.replaceAll(">", "_");
    str = str.replaceAll(": ", "_");
    str = str.replaceAll(" ", "_");
    str = str.replaceAll("\\?", "_");

    /** If filename only contains of special chars */
    if (str.matches("[_]+"))
      str = "rssowl";

    return str;
  }

  /**
   * Escape any Ampersand from the given String.
   * 
   * @param str The String to escape any Ampersand.
   * @return String The String with escaped Ampersands.
   */
  public static String escapeAmpersands(String str) {
    if (str.indexOf('&') >= 0)
      return replaceAll(str, "&", "&&");

    return str;
  }

  /**
   * Trim the given String to the given Limit. Make it human readable, such as
   * it is tried to trim the text after a whitespace, in order to keep entire
   * words.
   * 
   * @param str The String to Trim
   * @param limit The max. number of characters
   * @return String The human readable trimmed String
   */
  public static String hrTrim(String str, int limit) {

    /** String does not contain a whitespace or is small */
    if (str.indexOf(' ') == -1 || str.length() < limit)
      return str;

    /** Substring to Limit */
    str = str.substring(0, limit);

    /** Cut after a whitespace */
    for (int a = limit - 1; a >= 0; a--)
      if (str.charAt(a) == ' ')
        return str.substring(0, a) + "...";

    return str;
  }

  /**
   * Returns TRUE in case the given String has a value that is not "".
   * 
   * @param str The String to check
   * @return boolean TRUE in case the String has an value not ""
   */
  public static boolean isset(String str) {
    return (str != null && str.length() > 0);
  }

  /**
   * Check if a given char is a terminating an URL. URL-terminating symbols are
   * whitespaces, single- and double quotes.
   * 
   * @param ch Any char
   * @return TRUE if the char is terminating
   */
  public static boolean isTerminating(String ch) {
    if (ch == null)
      return true;
    return (ch.equals(" ") || ch.equals("\n") || ch.equals(System.getProperty("line.separator")) || ch.equals("\t") || ch.equals("\"") || ch.equals("'"));
  }

  /**
   * Returns TRUE if the String only cosists of whitespaces or is null / empty.
   * 
   * @param str The string to check
   * @return boolean TRUE if the String only consists of whitespaces
   */
  public static boolean isWhiteSpaceOrEmpty(String str) {
    return (!StringShop.isset(str) || RegExShop.WHITESPACE_PATTERN.matcher(str).matches());
  }

  /**
   * Trims the given String to the given length and appends "..." Also replaces
   * all occurances of "&" with "&&" if the String is used as title for controls
   * that display "&" as mnemonic.
   * 
   * @param str The String to Trim
   * @param length The max. length of the String
   * @param escapeMnemonics If TRUE all "&" will be replaced with "&&"
   * @return String The trimmed String
   */
  public static String pointTrim(String str, int length, boolean escapeMnemonics) {

    /** Remove mnemonics if needed and replace "&" with "&&" */
    if (escapeMnemonics)
      str = escapeAmpersands(str);

    /** Return a Substring and append "..." */
    return (str.length() >= length) ? str.substring(0, length) + "..." : str;
  }

  /**
   * Substitute wildcards in a String and return it
   * 
   * @param str The String to format
   * @param wildcard Array of wildcards
   * @param substitution Array of wildcards for the substitution of the
   * wildcards.
   * @return String The formatted String
   */
  public static String printf(String str, String[] wildcard, String[] substitution) {

    /** Replace each wildcard with its substitution */
    for (int i = 0; i < wildcard.length; i++)
      str = StringShop.replaceAll(str, wildcard[i], substitution[i]);

    return str;
  }

  /**
   * This method does exactly the same as String.replaceAll() with the
   * difference that no regular expressions are used to perform the replacement.
   * 
   * @param str The source String to search and replace
   * @param search The search term that should get replaced
   * @param replace The value that replaces the search term
   * @return String The new String with all replaced search terms
   */
  public static String replaceAll(String str, String search, String replace) {
    int start = 0;
    int pos;
    StringBuffer result = new StringBuffer(str.length());
    while ((pos = str.indexOf(search, start)) >= 0) {
      result.append(str.substring(start, pos));
      result.append(replace);
      start = pos + search.length();
    }
    result.append(str.substring(start));

    return result.toString();
  }

  /**
   * Remove HTML tags from the given String
   * 
   * @param str The String to remove the Tags from
   * @return String The Tag removed String
   */
  public static String stripTags(String str) {

    /** First Check if String contains any Tags at all */
    if (str == null || str.indexOf('<') == -1 || str.indexOf('>') == -1)
      return str;

    str = RegExShop.HTML_TAG_REGEX_PATTERN.matcher(str).replaceAll("");
    return str;
  }

  /**
   * Create a Vector containing all Strings from the String array
   * 
   * @param array The array to convert to a Vector
   * @return Vector Containing all Strings from the Array
   */
  public static Vector toVector(String[] array) {
    Vector vector = new Vector();
    for (int a = 0; a < array.length; a++)
      vector.add(array[a]);
    return vector;
  }

  /**
   * Convert the non ASCII-characters of a String into Unicode HTML entities.
   * 
   * @param str The String to convert
   * @return String The converted String
   */
  public static String unicodeToEntities(String str) {
    StringBuffer strBuf = new StringBuffer();

    /** For each character */
    for (int i = 0; i < str.length(); i++) {
      char ch = str.charAt(i);

      /** This is a non ASCII, non Whitespace character */
      if (!((ch >= 0x0020) && (ch <= 0x007e)) && !Character.isWhitespace(ch)) {
        strBuf.append("&#x");
        String hex = Integer.toHexString(ch & 0xFFFF);

        if (hex.length() == 2)
          strBuf.append("00");

        strBuf.append(hex).append(";");
      }

      /** This is an ASCII character */
      else {
        strBuf.append(ch);
      }
    }
    return strBuf.toString();
  }
}