/*
* Tyr is an AI for StarCraft: Broodwar, 
* 
* Please visit https://github.com/SimonPrins/Tyr for further information.
* 
* Copyright 2015 Simon Prins
*
* This file is part of Tyr.
* Tyr is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* Tyr is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with Tyr.  If not, see http://www.gnu.org/licenses/.
*/


package com.tyr;

import java.util.ArrayList;

import bwapi.Position;

/**
 * This class registers all settings.
 * All settings are available through static getter and setter methods.
 */
public class Settings
{
    /**
     * The number of workers that are to be sent to each gas.
     * Can be used to increase or decrease gas mining.
     */
    private static int workersPerGas = 1;
    
    /**
     * The maximum number of workers that is to be constructed.
     */
	private static int maximumWorkers = 45;

	/**
	 * The number of units that an army needs to have to be allowed to be sent out.
	 */
	private static int requiredSize = 20;

	/**
	 * Every time an army is sent out, the next army that will be sent out will be bigger.
	 * This determines the maximum size to which this will grow.
	 */
	private static int maximumSize = 40;
    
    /**
     * The distance to our starting location at which an enemy unit is considered an invader. 
     */
    private static int largeInvasionDist = 1024;
    
    /**
     * The distance to an expansion at which an enemy unit is considered an invader. 
     */
    private static int smallInvasionDist = 640;
    
    /**
     * The distance to our main an expansion has to be in order to be defended. 
     */
    private static int defendExpandDist = 1536;
    
    /**
     * The distance from the main at which we want to clear away blocking mineral patches. 
     */
    private static int blockingMineralDist = 1024;
	
	/**
	 * All ScannerListeners that subscribe to events from the scanner.
	 */
	private static ArrayList<ScannerListener> scannerListeners = new ArrayList<ScannerListener>();
	
	/**
	 * If this is true, no attack will be sent by the AttackTask.
	 * This is mostly for debug purposes.
	 */
	private static boolean blockAttack = false;

	/**
	 * The number of Siege Tanks we want defending each defensive position.
	 */
	private static int defensiveTanks = 0;

	/**
	 * Do we defend our main base?
	 */
	private static boolean defendMain = true;
	
	/**
	 * An alternative rally point for the army can be specified here.
	 */
	private static Position rallyPoint = null;
	
	/**
	 * Are we in debug mode?
	 */
	private static final boolean debug = false;
	
	/**
	 * Do we build our defenses close to our base?
	 */
	private static boolean closeDefense = false;
	
	/**
	 * Do we defend our start location?
	 */
	private static boolean defendStart = true;

	/**
	 * Do we attack neutral structures we encounter along the way when we attack?
	 */
	private static boolean attackNeutralStructures = false;
	
	/**
	 * Do we clear blocking minerals near the base?
	 */
	private static boolean clearMinerals = true;
    
    public static int getWorkersPerGas()
    {
    	return workersPerGas;
    }
    
    public static void setWorkersPerGas(int val)
    {
    	workersPerGas = val;
    }
    
    public static int getMaximumWorkers()
    {
    	return maximumWorkers;
    }
    
    public static void setMaximumWorkers(int val)
    {
    	maximumWorkers = val;
    }
    
    public static int getRequiredSize()
    {
    	return requiredSize;
    }
    
    public static void setRequiredSize(int val)
    {
    	requiredSize = val;
    }
    
    public static int getMaximumSize()
    {
    	return maximumSize;
    }
    
    public static void setMaximumSize(int val)
    {
    	maximumSize = val;
    }
    
    public static int getLargeInvasionDist()
    {
    	return largeInvasionDist;
    }
    
    public static void setLargeInvasionDist(int val)
    {
    	largeInvasionDist = val;
    }
    
    public static int getSmallInvasionDist()
    {
    	return smallInvasionDist;
    }
    
    public static void setSmallInvasionDist(int val)
    {
    	smallInvasionDist = val;
    }
    
    public static int getDefendExpandDist()
    {
    	return defendExpandDist;
    }
    
    public static void setDefendExpandDist(int val)
    {
    	defendExpandDist = val;
    }
    
    public static int getBlockingMineralDist()
    {
    	return blockingMineralDist;
    }
    
    public static void setBlockingMineralDist(int val)
    {
    	blockingMineralDist = val;
    }
    
    public static boolean getBlockAttack()
    {
    	return blockAttack;
    }
    
    public static void setBlockAttack(boolean val)
    {
    	blockAttack = val;
    }
    
    public static int getDefensiveTanks()
    {
    	return defensiveTanks;
    }
    
    public static void setDefensiveTanks(int val)
    {
    	defensiveTanks = val;
    }
    
    public static boolean getDefendMain()
    {
    	return defendMain;
    }

	public static void setDefendMain(boolean val) 
	{
		defendMain = val;
	}
    
    /**
     * Called by the Scanner when it starts eliminating.
     * This sends a message to all subscribers.
     */
    public static void scannerEliminating()
    {
    	for(ScannerListener listener : scannerListeners)
    		listener.onScannerEliminating();
    }
    
    /**
     * Subscribe a ScannerListener to scanner events.
     * @param listener The listener which wants to subscribe.
     */
    public static void addScannerListener(ScannerListener listener)
    {
    	scannerListeners.add(listener);
    }
    
    /**
     * An alternative rally point for the army.
     * @return An alternative rally point for the army or null if we use the default rally point.
     */
    public static Position getRallyPoint()
    {
    	return rallyPoint;
    }
    
    /**
     * Set an alternative rally point for the army.
     * @param val The alternative rally point for the army, or null if the default rally point should be used.
     */
	public static void setRallyPoint(Position val) 
	{
		rallyPoint = val;
	}
	
	/**
	 * Are we in debug mode?
	 * @return Are we in debug mode?
	 */
	public static boolean getDebug()
	{
		return debug;
	}
	
	/**
	 * Set whether we defend our start location.
	 * @param val Do we defend our start location?
	 */
	public static void setDefendStart(boolean val)
	{
		defendStart = val;
	}
	
	/**
	 * Do we defend our start location?
	 * @return Do we defend our start location?
	 */
	public static boolean getDefendStart()
	{
		return defendStart;
	}
	
	/**
	 * Set whether we build our defenses close to our base.
	 * @param val Do we build our defenses close to our base?
	 */
	public static void setCloseDefense(boolean val)
	{
		closeDefense = val;
	}
	
	/**
	 * Do we build our defenses close to our base?
	 * @return Do we build our defenses close to our base?
	 */
	public static boolean getCloseDefense()
	{
		return closeDefense;
	}
	
	/**
	 * Do we attack neutral structures we encounter along the way when we attack?
	 * @param val Do we attack neutral structures we encounter along the way when we attack?
	 */
	public static void setAttackNeutralStructures(boolean val)
	{
		attackNeutralStructures = val;
	}

	/**
	 * Do we attack neutral structures we encounter along the way when we attack?
	 * @return Do we attack neutral structures we encounter along the way when we attack?
	 */
	public static boolean attackNeutralStructures()
	{
		return attackNeutralStructures;
	}

	/**
	 * Do we clear blocking minerals near the base?
	 * @param val Do we clear blocking minerals near the base?
	 */
	public static void setClearMinerals(boolean val)
	{
		clearMinerals = val;
	}
	
	/**
	 * Do we clear blocking minerals near the base?
	 * @return Do we clear blocking minerals near the base?
	 */
	public static boolean getClearMinerals()
	{
		return clearMinerals;
	}
}
