/*******************************************************************************
 * Copyright (c) 2000, 2004 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 API and implementation
 *******************************************************************************/

package org.eclipse.jst.ws.internal.common;

import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;

import org.eclipse.jdt.core.JavaConventions;

/**
  * This class contains some useful string utilities that are not provided by
  * either String or StringBuffer.
  *
  * @author Peter Moogk
  * @date   July 13, 2000
**/
public final class StringUtils
{

  // Copyright
  public static final String copyright = "(c) Copyright IBM Corporation 2000, 2002.";

  /**
  * The platform-specific line separator.
  */
  public static final String NEWLINE = System.getProperty("line.separator");

  private StringUtils(){};

  /**
    * This method splits a single line of text into multiple lines
    * based on a maximum line length.  The method will try to fit as
    * many words as possible onto a line without exceeding the maximum
    * line length.  Note: the only case where a line might exceed the
    * maximum is if a single word is longer than the maximum.
  **/
  public static String[] splitter( String text, int max_length )
  {
    Vector          return_text = new Vector(20);
    String[]        return_str;
    int             index = 0;

    while( index < text.length() )
    {
      String str = text.substring( index, Math.min( max_length + index,
                                                    text.length() ) );
      int space_index = str.lastIndexOf( " " );

      if( index + str.length() < text.length() &&
          text.charAt( index + str.length() - 1 ) != ' ' &&
          text.charAt( index + str.length() ) != ' ' &&
          space_index != -1 )
      {
        return_text.addElement( str.substring( 0, space_index ) );
        index += space_index + 1;
      }
      else
      {
        return_text.addElement( str.trim() );
        index += str.length();
      }
    }

    return_str = new String[return_text.size()];

    for( index = 0; index < return_text.size(); index++ )
    {
      return_str[index] = (String)(return_text.elementAt(index));
    }

    return return_str;
  }

  /**
    * This method returns a string with a repeated number of characters.
  **/
  static public String repeat( char the_char, int count )
  {
    StringBuffer buf = new StringBuffer( count );

    for( int index = 0; index < count; index++ )
    {
      buf.append( the_char );
    }

    return buf.toString();
  }

  /**
    * This method flattens an array of arguments to a string.
    * The method respects embedded whitespace and quotes.
    * <ul>
    * <li>Any argument with embedded whitespace will be flattened out
    * with enclosing quotes. For example, the single argument
    * <u>Hello World</u>
    * will be returned as
    * <u>"Hello World"</u>.
    * <li>Any argument with quotes will be flattened out with the
    * quotes escaped. For example, the single argument
    * <u>"Happy days"</u>
    * will be returned as
    * <u>\"Happy days\"</u>.
    * </ul>
    * @param arguments The array of strings to flatten.
    * @return the flattened string.
  */
  static public String flattenArguments ( String[] arguments )
  {
    StringBuffer buf = new StringBuffer();

    for (int i=0; i<arguments.length; i++)
    {
      //
      // Append a separator (except the first time).
      //
      if (i > 0) buf.append(' ');

      //
      // Look for whitespace.
      //
      boolean whitespace = false;
      char[] chars = arguments[i].toCharArray();
      for (int j=0; !whitespace && j<chars.length; j++)
      {
        if (Character.isWhitespace(chars[j]))
        {
          whitespace = true;
        }
      }

      //
      // Append the argument, quoted as necessary.
      //
      if (whitespace) buf.append('"');
      for (int j=0; j<chars.length; j++)
      {
        if (chars[j] == '"') buf.append('\\');
        buf.append(chars[j]);
      }
      if (whitespace) buf.append('"');
    }

    return buf.toString();
  }

  /**
    * This method parses whitespace-delimitted filenames from
    * the given <code>input</code> stream. <b>Limitation:</b>
    * Quoted filenames or filenames with embedded whitespace
    * are not currently supported.
    * @param input The input stream.
    * @return An enumeration of filenames from the stream.
  */
  static public Enumeration parseFilenamesFromStream ( InputStream input )
  throws IOException
  {
    Vector filenames = new Vector(64,64);
    StringBuffer buffer = null;
    byte state = STATE_WS;
    int ic = input.read();
    while (ic >= 0)
    {
      char c = (char)ic;
      switch (state)
      {
        case STATE_WS:
          if (!Character.isWhitespace(c))
          {
            buffer = new StringBuffer();
            buffer.append(c);
            state = STATE_NWS;
          }
          break;
        case STATE_NWS:
          if (!Character.isWhitespace(c))
          {
            buffer.append(c);
          }
          else
          {
            String filename = buffer.toString();
            filenames.add(filename);
            buffer = null;
            state = STATE_WS;
          }
          break;
        default:
          break;
      }
      ic = input.read();
    }
    return filenames.elements();
  }

  private static final byte STATE_WS = 0;
  private static final byte STATE_NWS = 1;


  /**
  * Returns true is the type passed in is a primtive java type
  * @param class name String
  * @return true is primitive type
  */
  public static boolean isPrimitiveType(String typeName) 
  {

    if (typeName.equalsIgnoreCase("boolean") ||
      typeName.equalsIgnoreCase("byte") ||
      typeName.equalsIgnoreCase("double") ||
      typeName.equalsIgnoreCase("float") ||
      typeName.equalsIgnoreCase("int") ||
      typeName.equalsIgnoreCase("long") ||
      typeName.equalsIgnoreCase("short") ||
      typeName.equalsIgnoreCase("char"))
      return true;
    return false;

  }

  /**
  * The method replace the characters that are allowed in URIs
  * and not allowed in Java class names to an underscore ('_')
  * @param URI String
  * @return valid Java class name String
  */
  public static String URI2ClassName( String uri ) {
    String className = uri;
    for ( int i = 0; i < URI_SYMBOLS.length; i++ ) {
    	className = className.replace ( URI_SYMBOLS[i], UNDERSCORE );
    }
    return className;
  }

  private static final char[] URI_SYMBOLS = {'-', '~', '#', '/', '.'};
  private static final char UNDERSCORE = '_';


  /**
   * This returns a valid Java identifier based on the given name. 
   * (follows JAX-RPC 1.0 Public Review Draft 2 recommendations)
   */
  public static String javaIdentifierFor(String localName)
  {
    StringBuffer result = new StringBuffer();
    boolean skipped = false;
    for (int i = 0, length = localName.length(); i < length; ++i)
    {
      char character = localName.charAt(i);
      if (Character.isJavaIdentifierPart(character) && !isDelimiter(character))
      {
        if (skipped && result.length() != 0)
        {
          character = Character.toUpperCase(character);
        }
        result.append(character);
        skipped = false;
      }
      else
      {
        skipped =true;
      }
    }

    if (!JavaConventions.validateIdentifier(result.toString()).isOK())
    {
      result.insert(0, "_");
    }

    return result.toString();
  }

  private static boolean isDelimiter(char character)
  {
    return "\u002D\u002E\u003A\u005F\u00B7\u0387\u06DD\u06DE".indexOf(character) != -1;
  }
  
  
}
