package org.smartframework.common;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.smartframework.common.utils.ExDateUtils;

public class DataObject extends HashMap {
    private static final long serialVersionUID = 4336838378135065157L;
    private boolean isModified = false;
    private Map oldValues = new HashMap(100);
    private Map metaData = new HashMap(100);
    private final Map<String, String> lowerCaseMap = new HashMap();

    public DataObject() {
        super(100);
    }

    public DataObject(Map dataMap) {
        this.putAll(dataMap);
    }

    public DataObject(String tableName, String _tablePK) {
        super(100);
        this.put("rowStatus", "new");
        String key1 = "pk_" + tableName;
        this.put(key1, _tablePK);
        String key2 = key1 + "_" + _tablePK;
        this.put(key2, (Object)null);
        this.setModified(false);
    }

    public DataObject(String tableName, String _tablePK, Map rowData) {
        this.putAll(rowData);
        this.oldValues.putAll(rowData);
        this.put("rowStatus", "edit");
        String key1 = "pk_" + tableName;
        this.put(key1, _tablePK);
        String key2 = key1 + "_" + _tablePK;
        this.put(key2, String.valueOf(rowData.get(_tablePK)));
        this.setModified(false);
    }

    public void checkDataModified() {
        if(this.oldValues.isEmpty()) {
            String status = (String)this.get("rowStatus");
            if("new".equalsIgnoreCase(status)) {
                this.setModified(true);
                return;
            }
        }

        Iterator iter = this.oldValues.keySet().iterator();

        while(true) {
            while(iter.hasNext()) {
                String key = (String)iter.next();
                Object oldValue = this.oldValues.get(key);
                Object newValue = this.get(key);
                int b;
                if(newValue != null && newValue instanceof List) {
                    List temp = (List)newValue;

                    for(b = 0; b < temp.size(); ++b) {
                        if(temp.get(b) instanceof DataObject) {
                            ((DataObject)temp.get(b)).checkDataModified();
                        }
                    }
                } else if(!"created".equalsIgnoreCase(key) && !"updated".equalsIgnoreCase(key)) {
                    if(oldValue == null && newValue == null) {
                        this.remove(key);
                    } else if(oldValue != null && oldValue.equals(newValue)) {
                        this.remove(key);
                    } else if(oldValue == newValue) {
                        this.remove(key);
                    } else {
                        if(oldValue != null && oldValue instanceof Date && newValue != null) {
                            if(newValue instanceof String) {
                                newValue = ExDateUtils.parseDate((String)newValue);
                            }

                            if(((Date)oldValue).getTime() == ((Date)newValue).getTime()) {
                                this.remove(key);
                                continue;
                            }
                        }

                        if(oldValue != null && oldValue instanceof Long && newValue != null && newValue instanceof String) {
                            long a = ((Long)oldValue).longValue();
                            long c = Long.parseLong((String)newValue);
                            if(a == c) {
                                this.remove(key);
                                continue;
                            }
                        }

                        if(oldValue != null && oldValue instanceof Integer && newValue != null && newValue instanceof String) {
                            int a = ((Integer)oldValue).intValue();
                            b = Integer.parseInt((String)newValue);
                            if(a == b) {
                                this.remove(key);
                                continue;
                            }
                        }

                        this.setModified(true);
                    }
                } else {
                    this.remove(key);
                }
            }

            return;
        }
    }

    public boolean isModified() {
        return this.isModified;
    }

    public void setModified(boolean isModified) {
        this.isModified = isModified;
        if(isModified) {
            this.put("rowModified", "true");
        } else {
            this.put("rowModified", "false");
        }

    }

    public Object put(Object key, Object value) {
        Object oldKey = this.lowerCaseMap.put(key.toString().toLowerCase(), key.toString());
        Object oldValue = super.remove(oldKey);
        String _key = key.toString();
        if(value instanceof List) {
            List newList = (List)value;
            List oldList = (List)this.get(_key);
            if(oldList != null) {
                if(oldList.size() == newList.size()) {
                    for(int i = 0; i < newList.size(); ++i) {
                        Map newRow = (Map)newList.get(i);
                        if(oldList != null && i < oldList.size()) {
                            Map oldRow = (Map)oldList.get(i);
                            oldRow.putAll(newRow);
                        }
                    }
                } else {
                    super.put(_key, value);
                }
            } else {
                super.put(_key, value);
            }
        } else {
            super.put(_key, value);
        }

        return oldValue;
    }

    public void setRelationData(Object key, Object value) {
        this.put(key, value);
        this.oldValues.put(key, value);
    }

    public boolean containsKey(Object key) {
        Object realKey = this.lowerCaseMap.get(key.toString().toLowerCase());
        return super.containsKey(realKey);
    }

    public Object get(Object key) {
        Object realKey = this.lowerCaseMap.get(key.toString().toLowerCase());
        return super.get(realKey);
    }

    public void putAll(Map m) {
        Iterator iter = m.keySet().iterator();

        while(iter.hasNext()) {
            Object key = iter.next();
            Object value = m.get(key);
            this.put(key, value);
        }

    }

    public Object remove(Object key) {
        Object realKey = this.lowerCaseMap.remove(key.toString().toLowerCase());
        return super.remove(realKey);
    }

    public Object clone() {
        DataObject target = new DataObject();

        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            oos.close();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream bis = new ObjectInputStream(bais);
            target = (DataObject)bis.readObject();
        } catch (Exception var6) {
            var6.printStackTrace();
        }

        target.setOldValues(this.oldValues);
        return target;
    }

    public String getString(Object key) {
        Object value = this.get(key);
        return value instanceof String?(String)value:(value == null?null:String.valueOf(value));
    }

    public Integer getInt(Object key) {
        Object value = this.get(key);
        return value instanceof Integer?(Integer)value:(value == null?null:Integer.valueOf(Integer.parseInt(String.valueOf(value))));
    }

    public Long getLong(Object key) {
        Object value = this.get(key);
        return value instanceof Integer?new Long((long)((Integer)value).intValue()):(value == null?null:Long.valueOf(Long.parseLong(String.valueOf(value))));
    }

    public Date getDate(Object key) {
        Object value = this.get(key);
        return value instanceof Date?(Date)value:(value == null?null:(value instanceof String?("".equalsIgnoreCase(value.toString())?null:ExDateUtils.parseDate(value.toString())):null));
    }

    public List getList(Object key) {
        Object value = this.get(key);
        return value instanceof List?(List)value:(value == null?null:null);
    }

    public boolean getBoolean(Object key) {
        Object value = this.get(key);
        return value instanceof Boolean?((Boolean)value).booleanValue():(value == null?false:false);
    }

    public void setReadOnly(boolean readOnly) {
        this.put("readOnly", Boolean.valueOf(readOnly));
    }

    public boolean isReadOnly() {
        return this.get("readOnly") != null?((Boolean)this.get("readOnly")).booleanValue():false;
    }

    public void setRowStatus(String rowStatus) {
        this.put("rowStatus", rowStatus);
    }

    public String getRowStatus() {
        return (String)this.get("rowStatus");
    }

    public boolean isNewRow() {
        return this.getRowStatus() != null && "New".equalsIgnoreCase(this.getRowStatus());
    }

    public void loadExtendData(DataObject extendDO) {
        this.putAll(extendDO);
        this.oldValues.putAll(extendDO.oldValues);
    }

    protected void setOldValues(Map oldValues) {
        this.oldValues = oldValues;
    }

    public void setPkValue(String tablePK, Object pkValue) {
        this.put(tablePK, pkValue);
    }

    public Long getRowID(String tableName) {
        String key1 = "pk_" + tableName;
        String _tablePK = this.getString(key1);
        if(this.get(_tablePK) != null) {
            return this.getLong(_tablePK);
        } else {
            String key2 = key1 + "_" + _tablePK;
            return this.getLong(key2);
        }
    }
}
