/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.util;

import org.apache.commons.lang3.RandomStringUtils;

import divconq.lang.Memory;
import divconq.lang.TaskContext;
import divconq.struct.builder.MemoryBuilder;

public class StringUtil {
	/**
	 * check that characters are compatible with IntegerStruct value range
	 * 
	 * @param value characters to scan
	 * @return true if is an Integer
	 */
	  // as in - integer (long) that is database (mumps) compatible
	  public static boolean isDataInteger(CharSequence value) {
		  if (value.length() > 18)
			  return false;
		  
		  for (int i = 0; i < value.length(); i++) { 
			  char ch = value.charAt(i);
			  
			  if ((i==0) && ((ch != '-') && !Character.isDigit(ch)))
				  return false;
			  
			  if (!Character.isDigit(ch))
				  return false;
		  }
		  
		  return true;
	  }
	  
	  /**
	   * Attempts to parse a string into a long, using a default value if parse fails.
	   * (note that API wise, DivConq considers Integer to mean 64 bit)
	   * 
	   * @param value string to parse
	   * @param defvalue value to use if parse fails
	   * @return parsed number or default
	   */
	  public static long parseInt(String value, long defvalue) {
		  try {
			  return Long.parseLong(value);
		  }
		  catch (Exception x) {			  
		  }
		  
		  return defvalue;
	  }	  

	  /**
	   * Attempts to parse a string into a Long
	   * 
	   * @param value string to parse
	   * @return parsed number or null
	   */
		public static Long parseInt(String value) {
	        if (StringUtil.isEmpty(value)) 	        	
	        	return null;
	        
			  try {
				  return Long.parseLong(value);
			  }
			  catch (Exception x) {			  
			  }
	        
			return null;
		}

		/**
		 * check to see if characters contains anything but whitespace
		 *  
		 * @param str string to check
		 * @return true if contains non-whitespace
		 */
	  public static boolean isNotEmpty(CharSequence str) {
		  return !StringUtil.isEmpty(str);		  
	  }
	  
		/**
		 * check to see if characters contains only whitespace
		 *  
		 * @param str string to check
		 * @return true if contains only whitespace
		 */
	  public static boolean isEmpty(CharSequence str) {
		  if (str == null)
			  return true;
		  
	      int strLen = str.length();
	      
	      if (strLen == 0) 
	          return true;	      
	      
	      for (int i = 0; i < strLen; i++) 
	          if (!Character.isWhitespace(str.charAt(i))) 
	              return false;

	      return true;
	  }	  
	  
	  /*
	   * scan through characters and remove excess whitespace - per XML
	   * whitespace rules.
	   */
	    public static String deleteWhitespace(CharSequence str) {
	        if (StringUtil.isEmpty(str)) 
	            return null;
	        
	        int sz = str.length();
	        char[] chs = new char[sz];
	        int count = 0;
	        boolean needSpace = false;
	        boolean fndAnyNonSpace = false;
	        
	        for (int i = 0; i < sz; i++) {
	            if (!Character.isWhitespace(str.charAt(i))) {
	            	if (needSpace)
	            		chs[count++] = ' ';
	            		
	                chs[count++] = str.charAt(i);
	                fndAnyNonSpace = true;
	                needSpace = false;
	            }
	            else 
	            	needSpace = fndAnyNonSpace;
	        }
	        
	        return new String(chs, 0, count);
	    }
	    
	    /**
	     * replace single quotes with \'
	     * 
	     * @param str content to escape
	     * @return escaped content or null
	     */
	    public static String escapeSingleQuotes(String str) {
	    	if (str == null)
	    		return null;
	    	
	    	return str.replace("\'", "\\\'");
	    }

	    /**
	     * return Memory (utf-8) containing given string
	     * 
	     * @param att string to copy into memory
	     * @return memory containing the string
	     */
		public static Memory toMemory(String att) {
			MemoryBuilder rb = new MemoryBuilder();
			rb.write(att);
			return rb;
		}
		
		/**
		 * generate a user friendly security code - for user confirmation, password resets and the like
		 * 
		 * @return 12 character security code
		 */
		public static String buildSecurityCode() {
			return RandomStringUtils.random(12, "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789");
		}
		
		/**
		 * generate a user friendly security code - for user confirmation, password resets and the like
		 * 
		 * @return security code
		 */
		public static String buildSecurityCode(int chars) {
			return RandomStringUtils.random(chars, "ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789");
		}

		/**
		 * check characters to see if they contain restricted characters.  character x7F is not
		 * allowed.  characters x00 - x08 are not allowed.  characters x0E - x1F are not allowed.
		 * 
		 * @param str characters to check
		 * @return true if any restricted characters are present
		 */
		public static boolean containsRestrictedChars(CharSequence str) {
			if (str == null)
				return false;
			
			for (int i = 0; i < str.length(); i++) {
				int ch = str.charAt(i);
				
	            if ((ch < (int)0x9) || ((ch < (int)0x20) && (ch > (int)0xD)) || (ch == (int)0x7F)) 
	            	return true;
			}
			
			return false;
		}
	
		
		/**
		 * translate the token and parameters using the current or default locale
		 * 
		 * @param token name of the dictionary item to lookup
		 * @param params parameters to use when formatting the output
		 * @return translated and formatted text
		 */
	static public String tr(String token, Object... params) {
		return TaskContext.getOrHub().tr(token, params);		
	}
		
	/**
	 * translate a token and parameters using the current or default locale.
	 * if the first parameter is numeric and 1 then use the singular token
	 * otherwise lookup the plural token
	 * 
	 * @param pluraltoken name of the dictionary item to lookup
	 * @param singulartoken name of the dictionary item to lookup
	 * @param params parameters to use when formatting the output
	 * @return translated and formatted text
	 */
	static public String trp(String pluraltoken, String singulartoken, Object... params) {
		return TaskContext.getOrHub().trp(pluraltoken, singulartoken, params);		
	}	
}
