package wenrgise.common.utility;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import wenrgise.common.exception.EnrgiseApplicationException;
import wenrgise.common.exception.EnrgiseMessageKeyException;
import wenrgise.common.exception.EnrgiseSystemException;
import wenrgise.ejb.common.helper.QueryRow;
import wenrgise.ejb.common.helper.QueryValue;
import wenrgise.ejb.common.utility.DBUtilitiesBean;

public class EnrgiseUtil {
  public static void pageArrayCopier(ArrayList oSource, ArrayList oDest, int iSourcePos, int iLength) throws EnrgiseSystemException {
    if (oSource == null) {
      System.out.println("Source array is null");
      throw new EnrgiseSystemException();
    } 
    if (oDest == null) {
      System.out.println("Destination array is null");
      throw new EnrgiseSystemException();
    } 
    if (iLength < 0) {
      System.out.println("Length should be positive");
      return;
    } 
    if (oSource.size() < iSourcePos + iLength) {
      System.out.println("The source array is out of range");
      return;
    } 
    oDest.clear();
    for (int iIndex = iSourcePos; iIndex < iSourcePos + iLength; iIndex++)
      oDest.add(oSource.get(iIndex)); 
  }
  
  public static ArrayList addToList(ArrayList oList, Object[] obj) {
    for (int i = 0; i < obj.length; i++)
      oList.add(obj[i]); 
    return oList;
  }
  
  public static boolean checkString(String oInputString) {
    if (oInputString == null)
      return false; 
    String oString = new String(oInputString);
    oString = oString.trim();
    if (oString.equals(""))
      return false; 
    return true;
  }
  
  public static int compareDates(DateFormat dateFormat, String sOrigDate, String sRefDate) throws EnrgiseSystemException {
    if (!checkString(sOrigDate) || !checkString(sRefDate))
      return -2; 
    if (null == dateFormat) {
      dateFormat = DateFormat.getDateInstance(2);
      dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
    } 
    try {
      Date origDate = dateFormat.parse(sOrigDate);
      Date refDate = dateFormat.parse(sRefDate);
      return compareDates(origDate, refDate);
    } catch (ParseException oParEx) {
      System.out.println(String.valueOf("Date comparison problem ").concat(String.valueOf(oParEx.getMessage())));
      throw new EnrgiseSystemException();
    } 
  }
  
  public static int compareDates(Date origDate, Date refDate) {
    if (null == origDate || null == refDate)
      return -2; 
    if (origDate.equals(refDate))
      return 0; 
    if (origDate.before(refDate))
      return -1; 
    return 1;
  }
  
  public static int compareWithSysdate(Date origDate) throws EnrgiseSystemException {
    return compareDates(origDate, getSysDate());
  }
  
  public static int compareWithSysdate(DateFormat dateFormat, String sOrigDate) throws EnrgiseSystemException {
    if (!checkString(sOrigDate))
      return -2; 
    if (null == dateFormat)
      dateFormat = new SimpleDateFormat("dd-MMM-yyyy"); 
    try {
      Date origDate = dateFormat.parse(sOrigDate);
      return compareDates(origDate, getSysDate());
    } catch (ParseException oParEx) {
      System.out.println(String.valueOf("Date comparison problem ").concat(String.valueOf(oParEx.getMessage())));
      throw new EnrgiseSystemException();
    } 
  }
  
  public static Date getSysDate() throws EnrgiseSystemException {
    Date sysDate = null;
    DBUtilitiesBean oBean = new DBUtilitiesBean();
    ArrayList oList = oBean.executeQuery("SELECT sysdate FROM dual");
    if (null != oList) {
      QueryRow oRow = oList.get(0);
      QueryValue oValue = oRow.get("sysDate");
      return oValue.getDate();
    } 
    return null;
  }
  
  public static Object setFieldValue(Object obj, String sItem, String sItemValue) throws EnrgiseSystemException {
    try {
      Class oClass = obj.getClass();
      String sSetterMethod = getSetterMethodName(sItem);
      String oStr = new String();
      Class[] oCls = { oStr.getClass() };
      Method oMethod = oClass.getMethod(sSetterMethod, oCls);
      Object[] oParams = { sItemValue };
      return oMethod.invoke(obj, oParams);
    } catch (NoSuchMethodException oNsEx) {
      throw new EnrgiseSystemException(oNsEx);
    } catch (IllegalAccessException oIlEx) {
      throw new EnrgiseSystemException(oIlEx);
    } catch (InvocationTargetException oInEx) {
      throw new EnrgiseSystemException(oInEx);
    } 
  }
  
  public static Object getFieldValue(Object obj, String sItem) throws EnrgiseSystemException {
    try {
      Class oClass = obj.getClass();
      String sGetterMethod = getGetterMethodName(sItem);
      Method oMethod = oClass.getMethod(sGetterMethod, null);
      return oMethod.invoke(obj, null);
    } catch (NoSuchMethodException oNsEx) {
      throw new EnrgiseSystemException(oNsEx);
    } catch (IllegalAccessException oIlEx) {
      throw new EnrgiseSystemException(oIlEx);
    } catch (InvocationTargetException oInEx) {
      throw new EnrgiseSystemException(oInEx);
    } 
  }
  
  public static String getGetterMethodName(String sItem) {
    String sFirstString = sItem.substring(0, 1);
    String sRestString = sItem.substring(1);
    String sFirst = sFirstString.toUpperCase();
    return String.valueOf(String.valueOf("get").concat(String.valueOf(sFirst))).concat(String.valueOf(sRestString));
  }
  
  public static String getSetterMethodName(String sItem) {
    String sFirstString = sItem.substring(0, 1);
    String sRestString = sItem.substring(1);
    String sFirst = sFirstString.toUpperCase();
    return String.valueOf(String.valueOf("set").concat(String.valueOf(sFirst))).concat(String.valueOf(sRestString));
  }
  
  public static void checkDuplicate(ArrayList oList, String[] sItems, String sFieldKey, ArrayList oExceptionList) throws EnrgiseSystemException {
    int index = 0;
    Object[] oItemArray = null;
    String[] oStatusArray = null;
    ArrayList oRowList = new ArrayList();
    int iSize = oList.size();
    if (sItems != null) {
      oItemArray = (Object[])Array.newInstance(Class.forName("java.lang.String"), iSize);
      oStatusArray = (String[])Array.newInstance(Class.forName("java.lang.String"), iSize);
    } else {
      return;
    } 
    if (null != sItems) {
      Iterator oIt = oList.iterator();
      while (oIt.hasNext()) {
        Object obj = oIt.next();
        oItemArray[index] = getAllFieldsValue(obj, sItems);
        oStatusArray[index++] = (String)getFieldValue(obj, "status");
      } 
    } 
    for (int iSource = 0; iSource < iSize; iSource++) {
      if (null != oItemArray[iSource])
        if (null == oStatusArray[iSource] || !oStatusArray[iSource].equals("D"))
          for (int iTarget = iSource + 1; iTarget < iSize; iTarget++) {
            if (null != oItemArray[iTarget])
              if (null == oStatusArray || !oStatusArray[iTarget].equals("D"))
                if (compareObject(oItemArray[iSource], oItemArray[iTarget])) {
                  ArrayList oArgList = new ArrayList();
                  Integer oRow = new Integer(iSource + 1);
                  if (null != sFieldKey) {
                    MessageKey oMessageKey = new MessageKey(sFieldKey);
                    oArgList.add(oMessageKey);
                    oArgList.add(oRow);
                    oExceptionList.add(new EnrgiseMessageKeyException("wenrgise.common.field.combinatonNotUnique", oArgList, "E"));
                  } else {
                    oArgList.add(oRow);
                    oExceptionList.add(new EnrgiseApplicationException("wenrgise.common.duplicatefound", oArgList, "E"));
                  } 
                }   
          }   
    } 
  }
  
  public static void checkDuplicate(ArrayList oList, String sItem, String sFieldKey, ArrayList oExceptionList, boolean bCheckStatus) throws EnrgiseSystemException {
    int index = 0;
    Object[] oItemArray = null;
    String[] oStatusArray = null;
    if (null == oList)
      return; 
    int iSize = oList.size();
    if (null != sItem) {
      oItemArray = (Object[])Array.newInstance(sItem.getClass(), iSize);
      if (bCheckStatus)
        oStatusArray = (String[])Array.newInstance(sItem.getClass(), iSize); 
    } else {
      oItemArray = (Object[])Array.newInstance(oList.get(0).getClass(), iSize);
    } 
    Iterator oIt = oList.iterator();
    while (oIt.hasNext()) {
      Object obj = oIt.next();
      if (null != sItem) {
        oItemArray[index] = getFieldValue(obj, sItem);
        oStatusArray[index++] = (String)getFieldValue(obj, "status");
        continue;
      } 
      oItemArray[index++] = obj;
    } 
    for (int iSource = 0; iSource < iSize; iSource++) {
      if (null != oItemArray[iSource])
        if (null == oStatusArray[iSource] || !oStatusArray[iSource].equals("D"))
          for (int iTarget = iSource + 1; iTarget < iSize; iTarget++) {
            if (null != oItemArray[iTarget])
              if (null == oStatusArray || !oStatusArray[iTarget].equals("D"))
                if (compareObject(oItemArray[iSource], oItemArray[iTarget])) {
                  ArrayList oArgList = new ArrayList();
                  Integer oRow = new Integer(iSource + 1);
                  if (null != sFieldKey) {
                    MessageKey oMessageKey = new MessageKey(sFieldKey);
                    oArgList.add(oMessageKey);
                    oArgList.add(oRow);
                    oExceptionList.add(new EnrgiseMessageKeyException("wenrgise.common.field.duplicatefound", oArgList, "E"));
                  } else {
                    oArgList.add(oRow);
                    oExceptionList.add(new EnrgiseApplicationException("wenrgise.common.duplicatefound", oArgList, "E"));
                  } 
                }   
          }   
    } 
  }
  
  private static String getAllFieldsValue(Object obj, String[] sItems) throws EnrgiseSystemException {
    String sValues = " ";
    for (int i = 0; i < sItems.length; i++) {
      String sValue = (String)getFieldValue(obj, sItems[i]);
      if (null != sValue)
        sValues = String.valueOf(sValues).concat(String.valueOf(sValue.trim())); 
    } 
    return sValues.trim();
  }
  
  private static boolean compareObject(Object oSource, Object oTarget) {
    if (oSource.getClass().getName().equals("java.lang.String")) {
      String sSource = ((String)oSource).trim();
      String sTarget = ((String)oTarget).trim();
      if (sSource.equalsIgnoreCase(sTarget))
        return true; 
    } else if (oSource.equals(oTarget)) {
      return true;
    } 
    return false;
  }
  
  public static Timestamp convertToSqlDate(String sDate) throws EnrgiseSystemException {
    if (!checkString(sDate))
      return null; 
    DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");
    try {
      Date oDate = dateFormat.parse(sDate);
      return new Timestamp(oDate.getTime());
    } catch (ParseException oParEx) {
      System.out.println(String.valueOf("Date comparison problem ").concat(String.valueOf(oParEx.getMessage())));
      throw new EnrgiseSystemException();
    } 
  }
  
  public static String convertToString(Date oDate) {
    return (null != oDate) ? (new SimpleDateFormat("dd-MMM-yyyy")).format(oDate) : null;
  }
  
  public static boolean checkNumber(String sInputValue, int iScale, int iPrecision, String sSign) {
    String sLeft = null;
    String sRight = null;
    boolean bDecimal = false;
    if (checkString(sInputValue)) {
      String sVal = sInputValue.trim();
      int iDecimalIndex = sVal.indexOf(".");
      if (iDecimalIndex != -1) {
        sLeft = sVal.substring(0, iDecimalIndex);
        sRight = sVal.substring(iDecimalIndex + 1);
      } else {
        sLeft = sVal;
      } 
      if (!sLeft.startsWith("+") && !sLeft.startsWith("-"))
        sLeft = String.valueOf("+").concat(String.valueOf(sLeft)); 
      if (iPrecision == 0 && iScale == 0)
        return false; 
      try {
        if (iPrecision == 0) {
          long lVal = Long.parseLong(sVal);
          if (sLeft.length() <= iScale + 1) {
            if (Double.parseDouble(sLeft) == false && (sSign.equals("N") || sSign.equals("P")))
              return false; 
          } else {
            return false;
          } 
        } else {
          double d = Double.parseDouble(sVal);
        } 
      } catch (NumberFormatException oNumEx) {
        return false;
      } 
      if (sLeft.length() > iScale + 1)
        return false; 
      if (null != sRight)
        if (sRight.length() > iPrecision)
          return false;  
      if (null != sSign) {
        if (sSign.equals("N") && !sLeft.startsWith("-"))
          return false; 
        if (sSign.equals("P") && !sLeft.startsWith("+"))
          return false; 
        if (sSign.equals("NN") && sLeft.startsWith("-"))
          return false; 
        if (sSign.equals("NP") && sLeft.startsWith("+"))
          return false; 
      } 
    } 
    return true;
  }
}
