package com.jware.common.validator;

/**
 * @author jrmt
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

import java.io.Serializable;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.Field;
import org.apache.commons.validator.GenericTypeValidator;
import org.apache.commons.validator.GenericValidator;
import org.apache.commons.validator.UrlValidator;
import org.apache.commons.validator.ValidatorAction;
import org.apache.commons.validator.util.ValidatorUtils;
import org.apache.oro.text.perl.Perl5Util;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.validator.FieldChecks;
import org.apache.struts.validator.Resources;

/**
 * <p>This class performs validations.  The methods are can be configured to be 
 * used in the framework in the validation.xml file.  (See example webapp)</p>
 *
 * @author David Winterfeldt
*/

public class jwareValidator extends FieldChecks implements Serializable {

	/**
	 * Commons Logging instance.
	*/
	private static Log log = LogFactory.getLog(jwareValidator.class.getName());
    private static final jwareUrlValidator urlValidator = new jwareUrlValidator();
   

	//Begin Jware Extended part.**************************************************************
	
	//Two Integer field Compare Method*************************************************************
	public static boolean validateGreaterThan(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				double dValue = Double.parseDouble(value);
				double dValue2 = Double.parseDouble(value2);
				 
				if ( dValue <= dValue2 ) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validateLessThan(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				double dValue = Double.parseDouble(value);
				double dValue2 = Double.parseDouble(value2);
				 
				if ( dValue >= dValue2 ) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validateGreaterEqual(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				double dValue = Double.parseDouble(value);
				double dValue2 = Double.parseDouble(value2);
				 
				if ( dValue < dValue2 ) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validateLessEqual(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				double dValue = Double.parseDouble(value);
				double dValue2 = Double.parseDouble(value2);
				 
				if ( dValue > dValue2 ) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}


	//Two Date(String) field Compare Method*************************************************************
	public static boolean validateNextEqual(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (value.compareToIgnoreCase(value2) < 0) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validatePrevEqual(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (value.compareToIgnoreCase(value2) > 0) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}


	public static boolean validateNextThan(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (value.compareToIgnoreCase(value2) <= 0) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validatePrevThan(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (value.compareToIgnoreCase(value2) >= 0) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	public static boolean validateTwoFields(Object bean, ValidatorAction va,
											Field field, ActionMessages errors,
											HttpServletRequest request) {
		String value =
			ValidatorUtils.getValueAsString(bean, field.getProperty());
		String sProperty2 = field.getVarValue("secondProperty");
		String value2 = ValidatorUtils.getValueAsString(bean, sProperty2);

		if (!GenericValidator.isBlankOrNull(value)) {
			try {
				if (!value.equals(value2)) {
					errors.add(field.getKey(),
						Resources.getActionMessage(request, va, field));

					return false;
				}
			} catch (Exception e) {
				errors.add(field.getKey(),
					Resources.getActionMessage(request, va, field));

				return false;
			}
		}

		return true;
	}

	/**
	 * <p>Checks if the field isn't SBCS(Single Byte Chracter set)</p>
	 *
	 * @param 	bean 		The bean validation is being performed on.
	 * @param 	va 		The <code>ValidatorAction</code> that is currently being performed.
	 * @param 	field 		The <code>Field</code> object associated with the current field 
	 *				being validated.
	 * @param 	errors	 	The <code>ActionErrors</code> object to add errors to if any 
	 *                          validation errors occur.
	 * @param 	request         Current request object.
	*/

	public static boolean validateASCII(Object bean, 
							   ValidatorAction va, Field field, 
								ActionMessages errors, 
										   HttpServletRequest request) {

	   String value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        
	   if (!isASCII(value)) {
			errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
			return false;
	   }else{
		   return true;
	   }

	}

	/**
	 * 半角文字判定を行います。(半角カナを含みません。)
	 *
	 * @param value String
	 * @return boolean true：すべて半角文字  false：半角文字以外が含まれている
	 */
	public static boolean isASCII(String value) {

		for (int i = 0; i < value.length(); i++) {
			if (!isAsciiCharacter(value.charAt(i)))
				return false;
		}
		return true;
	}
	
	/**
	 * 半角文字判定を行います。(半角カナを含みます。)
	 *
	 * @param value char
	 * @return boolean true：半角文字  false：半角文字でない
	 */
	protected static boolean isAsciiCharacter(char value) {
		if ((value >= 0x0020 && value <= 0x007f)) {
			return true;
		}
		return false;
	}

	/**
	 * <p>Checks if the field isn't SBCS(Single Byte Chracter set)</p>
	 *
	 * @param 	bean 		The bean validation is being performed on.
	 * @param 	va 		The <code>ValidatorAction</code> that is currently being performed.
	 * @param 	field 		The <code>Field</code> object associated with the current field 
	 *				being validated.
	 * @param 	errors	 	The <code>ActionErrors</code> object to add errors to if any 
	 *                          validation errors occur.
	 * @param 	request         Current request object.
	*/

	public static boolean validateSBCS(Object bean, 
							   ValidatorAction va, Field field, 
								ActionMessages errors, 
										   HttpServletRequest request) {

	   String value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        
	   if (!isSBCS(value)) {
			errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
			return false;
	   }else{
		   return true;
	   }

	}

	/**
	 * 半角文字判定を行います。(半角カナを含みます。)
	 *
	 * @param value String
	 * @return boolean true：すべて半角文字  false：半角文字以外が含まれている
	 */
	public static boolean isSBCS(String value) {

		for (int i = 0; i < value.length(); i++) {
			if (!isSingleByteCharacter(value.charAt(i)))
				return false;
		}
		return true;
	}

	/**
	 * 半角文字判定を行います。(半角カナを含みます。)
	 *
	 * @param value char
	 * @return boolean true：半角文字  false：半角文字でない
	 */
	protected static boolean isSingleByteCharacter(char value) {
		if ((value >= 0x0020 && value <= 0x007f) || (value >= 0xff61 && value <= 0xff9f)) {
			return true;
		}
		return false;
	}
	
	
	
	/**
	 * <p>Checks if the field isn't Jancode and length of the field is 13.</p>
	 *
	 * @param 	bean 		The bean validation is being performed on.
	 * @param 	va 		The <code>ValidatorAction</code> that is currently being performed.
	 * @param 	field 		The <code>Field</code> object associated with the current field 
	 *				being validated.
	 * @param 	errors	 	The <code>ActionErrors</code> object to add errors to if any 
	 *                          validation errors occur.
	 * @param 	request         Current request object.
	*/

	public static boolean validateJancode(Object bean, 
							   ValidatorAction va, Field field, 
								ActionMessages errors, 
										   HttpServletRequest request) {

	   String value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        
	   if (!(value.length()==13)){
			return true;
	   }
	   
	   if (!GenericValidator.isLong(value)){
			errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
			return false;
	   }

	   if (!isJan13(value)) {
			errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
			return false;
	   }else{
		   return true;
	   }

	}
	
	private static boolean isJan13(String sJan){
		
		boolean bstate=false;
		int[] bJan = new int[13];
		int iTemp;
		
		if ( sJan.length() > 13 )
			return true;
		
		if ( sJan.startsWith("000000000") )
			return true;
		
		try{
			
			for(int i=0;i<bJan.length;i++) {
				bJan[i] = (int)sJan.charAt(i);
				bJan[i] = bJan[i]-0x30;
			}
			
			iTemp = bJan[1]+bJan[3]+bJan[5]+bJan[7]+bJan[9]+bJan[11];
			iTemp = (iTemp*3)+(bJan[0]+bJan[2]+bJan[4]+bJan[6]+bJan[8]+bJan[10]);
			
			if(iTemp%10==0)
				iTemp = 0;
			else
				iTemp = 10-(iTemp%10);

			
			if (iTemp==bJan[12]){bstate=true;}
			else{}
			
		}catch(Exception e){
			return false;
		}
		
		return bstate;
	
	}

	public static boolean validateEmailSemicolons(Object bean, ValidatorAction va,
			Field field, ActionMessages errors,
			HttpServletRequest request) {
		
		boolean bstate=true;
		String value = null;
		
		if(isString(bean)){
			value = (String)bean;
		}else{
			value=ValidatorUtils.getValueAsString(bean,field.getProperty());
		}
		
		String[] splitValue = value.split(";");
		for(int i=0 ; i<splitValue.length ; i++){
		    if(splitValue[i].trim() != null && splitValue[i].trim().length() > 0 && !Pattern.matches("[\\d[a-z]]+@[\\d[a-z]]+.[a-z]+|[\\d[a-z]]+@[\\d[a-z]]+.[a-z]+.[a-z]+|[\\d[a-z]]+@[\\d[a-z]]+.[a-z]+.[a-z]+.[a-z]+",splitValue[i])){
		    	errors.add(field.getKey(),Resources.getActionMessage(request, va, field));
		    	bstate = false;
		    	break;
		    }
		}
		return bstate;
	
	}
	
    public static boolean validateDatetime(Object bean, ValidatorAction va, Field field, ActionMessages errors, HttpServletRequest request)
    {
        java.util.Date result = null;
        String value = null;
        if(isString(bean))
            value = (String)bean;
        else
            value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        String datePattern = field.getVarValue("datePattern");
        String datePatternStrict = field.getVarValue("datePatternStrict");
        java.util.Locale locale = RequestUtils.getUserLocale(request, null);
        if(GenericValidator.isBlankOrNull(value))
            return true;
        try
        {
            if(datePattern != null && datePattern.length() > 0)
                result = GenericTypeValidator.formatDate(value, datePattern, false);
            else
            if(datePatternStrict != null && datePatternStrict.length() > 0)
                result = GenericTypeValidator.formatDate(value, datePatternStrict, true);
            else
                result = GenericTypeValidator.formatDate(value, locale);
        }
        catch(Exception e)
        {
            log.error(e.getMessage(), e);
        }
        if(result == null)
            errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
        return result != null;
    }
		
    public static boolean validateTime(Object bean, ValidatorAction va, Field field, ActionMessages errors, HttpServletRequest request)
    {
        java.util.Date result = null;
        String value = null;
        if(isString(bean))
            value = (String)bean;
        else
            value = ValidatorUtils.getValueAsString(bean, field.getProperty());
        String timePattern = field.getVarValue("timePattern");
        String timePatternStrict = field.getVarValue("timePatternStrict");
        java.util.Locale locale = RequestUtils.getUserLocale(request, null);
        if(GenericValidator.isBlankOrNull(value))
            return true;
        try
        {
            if(timePattern != null && timePattern.length() > 0)
                result = GenericTypeValidator.formatDate(value, timePattern, false);
            else
            if(timePatternStrict != null && timePatternStrict.length() > 0)
                result = GenericTypeValidator.formatDate(value, timePatternStrict, true);
            else
                result = GenericTypeValidator.formatDate(value, locale);
        }
        catch(Exception e)
        {
            log.error(e.getMessage(), e);
        }
        if(result == null)
            errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
        return result != null;
    }
    
    public static boolean validateUrlSimple(Object bean,
            ValidatorAction va, Field field,
            ActionMessages errors,
            HttpServletRequest request) {

		String value = null;
		if (isString(bean)) {
			value = (String) bean;
		} else {
			value = ValidatorUtils.getValueAsString(bean, field.getProperty());
		}
		
		if (GenericValidator.isBlankOrNull(value)) {
			return true;
		}
		
		// Get the options and schemes Vars
		boolean allowallschemes = "true".equalsIgnoreCase(field.getVarValue("allowallschemes"));
		int options = allowallschemes ? UrlValidator.ALLOW_ALL_SCHEMES : 0;
		
		if ("true".equalsIgnoreCase(field.getVarValue("allow2slashes"))) {
			options += UrlValidator.ALLOW_2_SLASHES;
		}
		
		if ("true".equalsIgnoreCase(field.getVarValue("nofragments"))) {
			options += UrlValidator.NO_FRAGMENTS;
		}
		
		String schemesVar = allowallschemes ? null : field.getVarValue("schemes");
		
		// No options or schemes - use GenericValidator as default
		if (options == 0 && schemesVar == null) {
			if (urlValidator.isValid(value)) {
				return true;
			} else {
				errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
				return false;
			}
		}
		
		// Parse comma delimited list of schemes into a String[]
		String[] schemes = null;
		if (schemesVar != null) {
		
			StringTokenizer st = new StringTokenizer(schemesVar, ",");
			schemes = new String[st.countTokens()];
			
			int i = 0;
			while (st.hasMoreTokens()) {
				schemes[i++] = st.nextToken().trim();
			}
		
		}
		
		// Create UrlValidator and validate with options/schemes
		UrlValidator urlValidator = new UrlValidator(schemes, options);
		if (urlValidator.isValid(value)) {
			return true;
		} else {
			errors.add(field.getKey(), Resources.getActionMessage(request, va, field));
			return false;
		}
	}    
	//END Jware Extended part.**************************************************************
	
}
