/**
 *  Copyright (C) 2002-2007  The FreeCol Team
 *
 *  This file is part of FreeCol.
 *
 *  FreeCol 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.
 *
 *  FreeCol 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 FreeCol.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.sf.freecol.client.gui.i18n;

import java.util.Locale;

import net.sf.freecol.util.test.FreeColTestCase;
import net.sf.freecol.common.model.*;

public class MessagesTest extends FreeColTestCase {

    public static final String noSuchKey = "should.not.exist.and.thus.return.null";

    public void tearDown(){
        Messages.setMessageBundle(Locale.US);
    }

    public void testMessageString() {

    	assertEquals("Press enter in order to end the turn.", Messages.message("infoPanel.endTurnPanel.text"));	
        assertEquals("Trade Advisor", Messages.message("menuBar.report.trade"));

        // With parameters
        assertEquals("Score: %score%    |    Gold: %gold%    |    Tax: %tax%%    |    Year: %year%", 
                     Messages.message("menuBar.statusLine"));

        // Long String
        assertEquals("Food is necessary to feed your colonists and to breed horses. "
                + "A new colonist is born whenever a colony has 200 units of food or more.",
                     Messages.message("model.goods.food.description"));

        // Message not found
        assertEquals(noSuchKey, Messages.message(noSuchKey));
    }

    public void testMessageStringVarargs() {
        
        try {
            Messages.message(null);
            fail("We should never get here");
        } catch (NullPointerException npe) {
            // Expected
        }

        assertEquals("Trade Advisor", Messages.message("menuBar.report.trade"));

        // With parameters for "Gold: %gold% | Tax: %tax%% | Year: %year%"
        assertEquals("Score: 1050    |    Gold: silver    |    Tax: 13%    |    Year: %year%", 
                     Messages.message("menuBar.statusLine", "%score%", "1050", "%gold%", "silver", "%tax%", "13"));

        // Long String
        assertEquals("Food is necessary to feed your colonists and to breed horses. "
                + "A new colonist is born whenever a colony has 200 units of food or more.", Messages.message(
                "model.goods.food.description"));

        try {
            Messages.message("menuBar.statusLine", "%tax%");
            fail("We should never have gotten here.");
        } catch (RuntimeException re) {
            // Expected
        }

        
        // Message not found
        assertEquals(noSuchKey, Messages.message(noSuchKey));
        
        assertEquals(noSuchKey, Messages.message(noSuchKey, 
                                            "%gold%", "silver", "%tax%", "13"));
    }

    public void testChangeLocaleSettings() {
        Messages.setMessageBundle(Locale.US);

        assertEquals("Trade Advisor", Messages.message("menuBar.report.trade"));

        Messages.setMessageBundle(Locale.GERMANY);

        assertEquals("Handelsberater", Messages.message("menuBar.report.trade"));
    }
    
    // Tests if messages with special chars (like $) are well processed
    public void testMessageWithSpecialChars(){
    	String errMsg = "Error setting up test.";
    	String expected = "You establish the colony of %colony%.";
        String message = Messages.message("model.history.FOUND_COLONY");
    	assertEquals(errMsg, expected, message);
        
        String colNameWithSpecialChars="$specialColName";
        errMsg = "Wrong message";
        expected = "You establish the colony of $specialColName.";
        try{
        	message = Messages.message("model.history.FOUND_COLONY","%colony%",colNameWithSpecialChars);
        }
        catch(IllegalArgumentException e){
        	if(e.getMessage().contains("Illegal group reference")){
        		fail("Does not process messages with special chars");
        	}
        	throw e;
        }
        assertEquals(errMsg, expected, message);
    }

    public void testStatesmanNameAndLabel() {

        Game game = getGame();

        UnitType statesman = spec().getUnitType("model.unit.elderStatesman");
        Unit unit = new Unit(game, game.getPlayer("model.nation.dutch"), statesman);

        assertNull(unit.getName());
        assertEquals("Elder Statesman", Messages.getName(unit));

        assertEquals("Elder Statesman",
                     Messages.getLabel(statesman, Unit.Role.DEFAULT));
        assertEquals("Scout (Elder Statesman)",
                     Messages.getLabel(statesman, Unit.Role.SCOUT));
        assertEquals("Soldier (Elder Statesman)",
                     Messages.getLabel(statesman, Unit.Role.SOLDIER));
        assertEquals("Dragoon (Elder Statesman)",
                     Messages.getLabel(statesman, Unit.Role.DRAGOON));
        assertEquals("Pioneer (Elder Statesman)",
                     Messages.getLabel(statesman, Unit.Role.PIONEER));
        assertEquals("Missionary (Elder Statesman)",
                     Messages.getLabel(statesman, Unit.Role.MISSIONARY));


        assertEquals(Unit.Role.DEFAULT, unit.getRole());
        assertEquals("Elder Statesman", Messages.getLabel(unit));

        unit.equipWith(spec().getEquipmentType("model.equipment.muskets"), true);
        assertEquals(Unit.Role.SOLDIER, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Soldier (Elder Statesman)", Messages.getLabel(unit));
        
        unit.equipWith(spec().getEquipmentType("model.equipment.horses"), true);
        assertEquals(Unit.Role.DRAGOON, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Dragoon (Elder Statesman)", Messages.getLabel(unit));

        unit.removeAllEquipment(true);
        unit.setName("MyName");
        assertEquals("MyName", unit.getName());
        assertEquals(Messages.getLabel(unit),
                     "Elder Statesman MyName", Messages.getLabel(unit));

        unit.equipWith(spec().getEquipmentType("model.equipment.muskets"), true);
        assertEquals(Unit.Role.SOLDIER, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Soldier MyName (Elder Statesman)", Messages.getLabel(unit));
        
        unit.equipWith(spec().getEquipmentType("model.equipment.horses"), true);
        assertEquals(Unit.Role.DRAGOON, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Dragoon MyName (Elder Statesman)", Messages.getLabel(unit));


    }

    public void testPioneerNameAndLabel() {

        Game game = getGame();

        UnitType pioneer = spec().getUnitType("model.unit.hardyPioneer");
        Unit unit = new Unit(game, game.getPlayer("model.nation.dutch"), pioneer);

        assertNull(unit.getName());
        assertEquals("Hardy Pioneer", Messages.getName(unit));

        assertEquals("Hardy Pioneer",
                     Messages.getLabel(pioneer, Unit.Role.DEFAULT));
        assertEquals("Scout (Hardy Pioneer)",
                     Messages.getLabel(pioneer, Unit.Role.SCOUT));
        assertEquals("Soldier (Hardy Pioneer)",
                     Messages.getLabel(pioneer, Unit.Role.SOLDIER));
        assertEquals("Dragoon (Hardy Pioneer)",
                     Messages.getLabel(pioneer, Unit.Role.DRAGOON));
        assertEquals("Hardy Pioneer", // default role
                     Messages.getLabel(pioneer, Unit.Role.PIONEER));
        assertEquals("Missionary (Hardy Pioneer)",
                     Messages.getLabel(pioneer, Unit.Role.MISSIONARY));


        assertEquals(Unit.Role.PIONEER, unit.getRole());
        assertEquals("Hardy Pioneer", Messages.getLabel(unit));

        unit.equipWith(spec().getEquipmentType("model.equipment.muskets"), true);
        assertEquals(Unit.Role.SOLDIER, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Soldier (Hardy Pioneer)", Messages.getLabel(unit));
        
        unit.equipWith(spec().getEquipmentType("model.equipment.horses"), true);
        assertEquals(Unit.Role.DRAGOON, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Dragoon (Hardy Pioneer)", Messages.getLabel(unit));

        unit.removeAllEquipment(true);
        unit.setName("MyName");
        assertEquals("MyName", unit.getName());
        assertEquals(Messages.getLabel(unit),
                     "Hardy Pioneer MyName (no tools)", Messages.getLabel(unit));

        unit.equipWith(spec().getEquipmentType("model.equipment.muskets"), true);
        assertEquals(Unit.Role.SOLDIER, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Soldier MyName (Hardy Pioneer)", Messages.getLabel(unit));
        
        unit.equipWith(spec().getEquipmentType("model.equipment.horses"), true);
        assertEquals(Unit.Role.DRAGOON, unit.getRole());
        assertEquals(Messages.getLabel(unit),
                     "Dragoon MyName (Hardy Pioneer)", Messages.getLabel(unit));


    }


    public void testTyped() {

    	Game game = getStandardGame();
    	game.setMap(getTestMap());
    	Colony colony = getStandardColony(7);

        colony.getTile().setExploredBy(colony.getOwner(), true);
        assertEquals(Messages.getName(colony.getTile()),
                     Messages.getName(colony.getTile().getType()));

        for (Building building : colony.getBuildings()) {
            assertEquals(Messages.getName(building),
                         Messages.getName(building.getType()));
        }

        for (TileImprovement tileImprovement : colony.getTile().getTileImprovements()) {
            assertEquals(Messages.getName(tileImprovement),
                         Messages.getName(tileImprovement.getType()));
        }

        colony.newTurn();

        for (Goods goods: colony.getCompactGoods()) {
            assertEquals(Messages.getName(goods),
                         Messages.getName(goods.getType()));
        }


    }



}
