package io.badgeup.sponge.event;

import io.badgeup.sponge.JSONSerializable;
import io.badgeup.sponge.Util;
import org.json.JSONArray;
import org.json.JSONObject;
import org.spongepowered.api.data.DataSerializable;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.cause.Cause;
import org.spongepowered.api.text.Text;

import java.lang.reflect.Method;
import java.util.List;
import java.util.UUID;

public class BadgeUpEvent {

    private String key;

    private UUID subject;

    // user provided data
    private JSONObject data;

    // BadgeUp event options
    private JSONObject options;

    private Modifier modifier;

    /**
     * Constructor for a BadgeUp event
     *
     * @param key the identifying string for this type of event
     * @param subject the subject string identifying the user that caused this
     *        event
     * @param modifier the metric impact this event will have
     */
    public BadgeUpEvent(String key, UUID subject, Modifier modifier) {
        this.key = key;
        this.subject = subject;
        this.modifier = modifier;
        this.data = new JSONObject();
        this.options = new JSONObject();
    }

    public String getKey() {
        return this.key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public UUID getSubject() {
        return this.subject;
    }

    /**
     * Add a custom key/value data pair
     *
     * @param key
     * @param value
     */
    @SuppressWarnings("rawtypes")
    public void addDataEntry(final String key, Object value) {
        if (value instanceof Player || value instanceof Cause || value instanceof Class) {
            return;
        }

        if (value instanceof DataSerializable) {
            if (value instanceof Text) {
                value = ((Text) value).toPlain();
            } else {
                JSONObject serializedObject = Util.dataContainerToJSONObject(((DataSerializable) value).toContainer());
                Util.cleanData(serializedObject);
                value = serializedObject;
            }
        } else if (value instanceof JSONSerializable) {
            value = ((JSONSerializable) value).toJSON();
        } else {
            if (value instanceof List) {
                JSONArray array = new JSONArray();
                for (Object entry : (List) value) {
                    if (!(entry instanceof DataSerializable)) {
                        return;
                    }
                    JSONObject serializedObject = Util
                            .dataContainerToJSONObject(((DataSerializable) entry).toContainer());
                    Util.cleanData(serializedObject);
                    array.put(serializedObject);
                }
                value = array;
            } else {
                Method toStringMethod;
                try {
                    toStringMethod = value.getClass().getMethod("toString");
                } catch (NoSuchMethodException e) {
                    // Can't be thrown since every class has a toString method
                    // through Object
                    return;
                }
                if (toStringMethod.getDeclaringClass() == Object.class) {
                    // toString has not been implemented and will only produce
                    // the class name + the object hash
                    // this is useless, so discard it
                    return;
                }
            }
        }
        this.data.put(key, value);
    }

    /**
     * Marks the event to be discarded (not stored) after it is processed
     */
    public void setDiscardable(boolean discardable) {
        if (discardable) {
            this.options.put("discard", discardable);
        } else {
            this.options.remove("discard");
        }
    }

    public JSONObject build() {
        return new JSONObject().put("key", this.key).put("subject", this.subject.toString()).put("data", this.data)
                .put("options", this.options)
                .put("modifier", new JSONObject().put(this.modifier.getOperation().getName(), this.modifier.getValue()));
    }

}

@@ -2231,30 +2231,16 @@
  %7D else 
-%7B%0A            
 if (valu
@@ -2268,28 +2268,24 @@
             
-   
- 
 JSONArray ar
@@ -2303,28 +2303,24 @@
 SONArray();%0A
-    
             
@@ -2367,28 +2367,24 @@
             
-   
- 
 if (!(entry 
@@ -2427,36 +2427,32 @@
                 
-    
 return;%0A        
@@ -2455,34 +2455,26 @@
             
-   
- 
 %7D%0A
-    
             
@@ -2512,20 +2512,16 @@
  = Util%0A
-    
         
@@ -2614,36 +2614,32 @@
                 
-    
 Util.cleanData(s
@@ -2648,36 +2648,32 @@
 ializedObject);%0A
-    
                 
@@ -2709,34 +2709,26 @@
             
-    %7D%0A    
+%7D%0A
             
@@ -2742,36 +2742,32 @@
  array;%0A        
-    
 %7D else %7B%0A       
@@ -2751,36 +2751,32 @@
        %7D else %7B%0A
-    
             Meth
@@ -2810,22 +2810,14 @@
     
-    
 try %7B%0A
-    
     
@@ -2897,20 +2897,16 @@
         
- 
-   
 %7D catch 
@@ -2929,28 +2929,24 @@
 eption e) %7B%0A
-    
             
@@ -3020,28 +3020,24 @@
             
- 
-   
 // through O
@@ -3050,36 +3050,32 @@
                 
-    
 return;%0A        
@@ -3074,34 +3074,26 @@
             
- 
-   %7D%0A    
+%7D%0A
             
@@ -3162,28 +3162,24 @@
             
- 
-   
 // toString 
@@ -3237,28 +3237,24 @@
             
-    
 // the class
@@ -3289,28 +3289,24 @@
             
-  
-  
 // this is u
@@ -3339,36 +3339,32 @@
             
-    
 return;%0A
             
@@ -3351,34 +3351,16 @@
 return;%0A
-                %7D%0A
         

Simplify if statement