/**
 * Copyright (C) 2014 t7seven7t
 */
package net.galaxygaming.dispenser.game.java;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;
import java.net.URL;

import org.apache.commons.lang.Validate;
import org.bukkit.configuration.file.FileConfiguration;

import net.galaxygaming.dispenser.game.Game;
import net.galaxygaming.dispenser.game.GameLoader;
import net.galaxygaming.dispenser.game.GameState;
import net.galaxygaming.dispenser.game.GameType;

/**
 * @author t7seven7t
 */
public abstract class JavaGame implements Game {

    /** The current game state */
    protected GameState state = GameState.INACTIVE;
    
    /** Name of this game instance */
    private String name;
    
    private GameType type;
    private GameLoader loader;
    private FileConfiguration config;
    private File file;
    private ClassLoader classLoader;
    
    protected final ClassLoader getClassLoader() {
        return classLoader;
    }
    
    @Override
    public final FileConfiguration getConfig() {
        return this.config;
    }
    
    /**
     * Gives the file associated with this game's config
     * @return config file
     */
    protected final File getFile() {
        return this.file;
    }
    
    @Override
    public final GameLoader getGameLoader() {
        return this.loader;
    }
    
    @Override
    public final GameState getState() {
        return this.state;
    }
    
    @Override
    public final GameType getType() {
        return this.type;
    }
    
    @Override
    public final String getName() {
        return this.name;
    }
    
    @Override
    public final void setName(String name) {
        this.name = name;
    }
    
    @Override
    public final boolean equals(Object o) {
        if (o == null) {
            return false;
        }
        
        if (getClass() != o.getClass()) {
            return false;
        }
        
        JavaGame other = (JavaGame) o;
        
        if (other.name == null || !other.name.equalsIgnoreCase(this.name)) {
            return false;
        }
        
        return true;
    }
    
    @Override
    public final int hashCode() {
        return name.hashCode();
    }
    
    public final InputStream getResource(String fileName) {
        Validate.notNull(fileName, "Filename cannot be null");
        
        try {
            URL url = getClassLoader().getResource(fileName);
            
            if (url == null) {
                return null;
            }
            
            URLConnection connection = url.openConnection();
            connection.setUseCaches(false);
            return connection.getInputStream();
        } catch (IOException e) {
            return null;
        }
    }
    
    JavaGame() {
        final ClassLoader classLoader = this.getClass().getClassLoader();
        if (!(classLoader instanceof GameClassLoader)) {
            throw new IllegalStateException("JavaGame requires " + GameClassLoader.class.getName());
        }
    }
    
    final void initialize(String name, FileConfiguration config, GameLoader loader, File file, ClassLoader classLoader) {
        this.name = name;
        this.config = config;
        this.loader = loader;
        this.file = file;
        this.classLoader = classLoader;
        
        onLoad();
    }
}

@@ -1959,37 +1959,148 @@
     
-JavaGame other = (JavaGame) o
+if (getClass() == o.getClass()) %7B            %0A            if (this.name.equalsIgnoreCase(((JavaGame) o).name)) %7B%0A                return true
 ;%0A  
@@ -2097,32 +2097,37 @@
 n true;%0A        
+ 
+   %7D
 %0A        if (oth
@@ -2123,40 +2123,71 @@
     
-if (other.name == null %7C%7C !other
+%7D else if (o.getClass() == String.class) %7B%0A            if (this
 .nam
@@ -2209,22 +2209,27 @@
 ase(
-this.name
+(String) o
 )) %7B%0A
+    
     
@@ -2235,39 +2235,42 @@
          return 
-false;%0A
+true;%0A    
         %7D%0A      
@@ -2263,32 +2263,33 @@
       %7D%0A        
+%7D
 %0A        return 
@@ -2284,27 +2284,28 @@
      return 
-tru
+fals
 e;%0A    %7D%0A   

optimize equals method for set.contains()