package com.enactor.pos;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import com.enactor.core.automation.AUT.AutomationException;

public final class PosUtility {
	
	private static final String[] CURRENCY_SYMBOLS = {"£","$","€"};
	private static final String[] WHITESPACES = {"&#160;","&nbsp;"};
	private static final Map<String, String> SPECIAL_CHARACTERS = new HashMap<String, String>() {
        {
            put("&#163;", "£");
            put("&#8364;", "€");
            put("&#36;", "$");
            put("&amp;", "&");
            put("&#160;", " ");
            put("<br>", " ");
            put("<b>", " ");
            put("</b>", " ");
            put("<i>", " ");
            put("</i>", " ");
            put("<u>", " ");
            put("</u>", " ");
        }
    };
	private static final Map<String, String> ESCAPE_REGEX = new HashMap<String, String>() {
        {
            put("\\(", "\\\\(");
            put("\\)", "\\\\)");
            put("\\[", "\\\\[");
            put("\\]", "\\\\]");
            put("\\{", "\\\\{");
            put("\\}", "\\\\}");
            put("\\*", "\\\\*");
        }
    };
	
	/*
	 * remove all currency symbols from supplied text
	 */
	public static String removeCurrency(String text) {
		String newString = text;
		for (String symbol : CURRENCY_SYMBOLS) {
			newString = newString.replace(symbol, "");
		}
		return newString;
	}
	
	/*
	 * remove all whitespaces from supplied text
	 */
	public static String removeWhitespaces(String text) {
		String newString = text;
		for (String symbol : WHITESPACES) {
			newString = newString.replace(symbol, "");
		}
		return newString;
	}
	
	/*
	 * remove all decimal codes from supplied text
	 */
	public static String replaceSpecialCharacters(String text) {
		String newString = text;
		for (Map.Entry<String, String> entry : SPECIAL_CHARACTERS.entrySet()) {
			newString= newString.replaceAll(entry.getKey(), entry.getValue());
		}
		return newString;
	}
	
	/**
	 * Split given string by given delimiter
	 * 
	 * <br><b>Example:</b> 	
	 * <br>
	 * <table><tr>
     *  <th>String</th>
     *  <th>Delimiter</th>
     *  <th>Result</th>
     * </tr>
     * <tr>
     * 	<td align=center>"username/password"</td>
     * 	<td align=center>"/"</td>
     * 	<td>["username","password"]</td>
     * </tr></table>
	 * 
	 * @param string
	 * @param delimiter
	 * @return List<String>
	 * @throws AutomationException 
	 */
	public static List<String> splitString(String string, String delimiter) throws AutomationException {		
		try {
			return Arrays.asList(string.split(delimiter));
		} catch (PatternSyntaxException e) {
			throw new AutomationException("Couldn't split string [" + string + "] using delimiter [" + delimiter + "]");
		}		
	}
	
	/*
	 * get month number 
	 * eg: 
	 * 		supply "February" will return 2
	 */
	public static int getMonthNumber(String monthName) throws AutomationException {
		Calendar calendar = Calendar.getInstance();
		Date date = null;
		try {
			date = new SimpleDateFormat("MMMMM").parse(monthName);
		} catch (ParseException e) {
			throw new AutomationException("Month : [" + monthName + "], ", e);
		}
		calendar.setTime(date);
		return calendar.get(Calendar.MONTH) + 1; // Month numbers starts from 0. eg: January = 0
	}
	
	/*
	 * get today's date in dd/MM/yy format as a string
	 * eg:
	 * get today's date - getDateString();
	 */
	public static String offsetInDays() {
		return offsetInDays(0);
	}
	
	/*
	 * get date in dd/MM/yy format as a string
	 * eg:
	 * tomorrow's date - getDateString(1);
	 * day before yesterday - getDateString(-2);
	 *  
	 */
	public static String offsetInDays(Integer different) {	
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy");		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, different);  
		
		String date = dateFormat.format(calendar.getTime()); 
		
		return date;
	}
	
	/**
	 * Matches a give text which starts and ends with a space 
	 * in a given text line.	 
	 *  
	 * <br>If you pass text "my text" to match, method tries to find the text " my text " in
	 * the input text 
	 * 
	 * <br><u>eg:</u> 	
	 * <br>&emsp; text = "my text"
	 * <br>&emsp; inputText = "This should match my text but not my text"
	 * <br>&emsp; returns true 
	 * <br>&emsp; method finds "This should match <b>my text</b> but not my text"
	 * 
	 * @param patternText
	 * @param inputText
	 * @return
	 */
	public static boolean textMatchingStartsAndEndsWithSpaces(String text, String inputText) {	
		text = prepareTextForRegex(text);
		String regEx = "(?<=\\s)" + text + "(?=\\s)";
		Pattern pattern = Pattern.compile(regEx);
    	Matcher matcher = pattern.matcher(inputText);
    	return matcher.find();
    }
	
	/**
	 * Matches a give text line starts with a given word 
	 *  
	 * <br><u>eg:</u> 	
	 * <br>&emsp; text = "R"
	 * <br>&emsp; inputText = "R My Item"
	 * <br>&emsp; returns true 
	 * <br>&emsp; method finds "<b>R</b> My Item"
	 * 
	 * @param patternText
	 * @param inputText
	 * @return
	 */
	public static boolean textMatchingStartWord(String text, String inputText) {
		String line = prepareTextForRegex(inputText.trim());
		String regEx = "^" + text + "(?=\\s)";
		Pattern pattern = Pattern.compile(regEx);
    	Matcher matcher = pattern.matcher(line);
    	return matcher.find();
    }
	
	/**
	 * Prepare text for regular expression match. 
	 * Escape certain charactors so it wont use in regex
	 * 
	 * eg: to match text " (Amount) " in another string using regex
	 * brackets need to be escaped.
	 *  " \\(Amount\\) "
	 *  
	 * @param text
	 * @return
	 */
	public static String prepareTextForRegex(String text) {
		String newString = text;
		for (Map.Entry<String, String> entry : ESCAPE_REGEX.entrySet()) {
			newString= newString.replaceAll(entry.getKey(), entry.getValue());
		}
		return newString;
	}

}
