content: /**
   * This file is part of Aion-Lightning <aion-lightning.org>.
   *
   *  Aion-Lightning 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 3 of the License, or
   *  (at your option) any later version.
   *
   *  Aion-Lightning 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 Aion-Lightning.
   *  If not, see <http://www.gnu.org/licenses/>.
   */
  package com.aionemu.gameserver.services.abyss;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import com.aionemu.commons.database.dao.DAOManager;
  import com.aionemu.gameserver.GameServer;
  import com.aionemu.gameserver.configs.main.RankingConfig;
  import com.aionemu.gameserver.dao.AbyssRankDAO;
  import com.aionemu.gameserver.model.AbyssRankingResult;
  import com.aionemu.gameserver.model.Race;
  import com.aionemu.gameserver.model.gameobjects.player.Player;
  import com.aionemu.gameserver.network.aion.serverpackets.SM_ABYSS_RANKING_LEGIONS;
  import com.aionemu.gameserver.network.aion.serverpackets.SM_ABYSS_RANKING_PLAYERS;
  import com.aionemu.gameserver.services.LegionService;
  import com.aionemu.gameserver.world.World;
  import com.aionemu.gameserver.world.knownlist.Visitor;
  
  import javolution.util.FastMap;
  
  /**
   * @author VladimirZ
   */
  public class AbyssRankingCache {
  
  	private int lastUpdate;
  	private final FastMap<Race, List<SM_ABYSS_RANKING_PLAYERS>> players = new FastMap<Race, List<SM_ABYSS_RANKING_PLAYERS>>();
  	private final FastMap<Race, SM_ABYSS_RANKING_LEGIONS> legions = new FastMap<Race, SM_ABYSS_RANKING_LEGIONS>();
  
  	public void reloadRankings() {
  		GameServer.log.debug("[AbyssRankingCache] Updating abyss ranking cache");
  		this.lastUpdate = (int) (System.currentTimeMillis() / 1000);
  		getDAO().updateRankList(RankingConfig.TOP_RANKING_MAX_OFFLINE_DAYS);
  
  		renewPlayerRanking(Race.ASMODIANS);
  		renewPlayerRanking(Race.ELYOS);
  
  		renewLegionRanking();
  
  		World.getInstance().doOnAllPlayers(new Visitor<Player>() {
  
  			@Override
  			public void visit(Player player) {
  				player.resetAbyssRankListUpdated();
  			}
  		});
  	}
  
  	/**
  	 * Renews the legion's rank and SM_ABYSS_RANKING_LEGIONS
  	 */
  	private void renewLegionRanking() {
  		Map<Integer, Integer> newLegionRankingCache = new HashMap<Integer, Integer>();
  		ArrayList<AbyssRankingResult> elyosRanking = getDAO().getAbyssRankingLegions(Race.ELYOS), asmoRanking = getDAO().getAbyssRankingLegions(Race.ASMODIANS);
  
  		legions.clear();
  		legions.put(Race.ASMODIANS, new SM_ABYSS_RANKING_LEGIONS(lastUpdate, asmoRanking, Race.ASMODIANS));
  		legions.put(Race.ELYOS, new SM_ABYSS_RANKING_LEGIONS(lastUpdate, elyosRanking, Race.ELYOS));
  
  		for (AbyssRankingResult result : elyosRanking) {
  			newLegionRankingCache.put(result.getLegionId(), result.getRankPos());
  		}
  		for (AbyssRankingResult result : asmoRanking) {
  			newLegionRankingCache.put(result.getLegionId(), result.getRankPos());
  		}
  
  		LegionService.getInstance().performRankingUpdate(newLegionRankingCache);
  	}
  
  	/**
  	 * Renews the player ranking by race
  	 *
  	 * @param race
  	 */
  	private void renewPlayerRanking(Race race) {
  		// delete not before new list is created
  		List<SM_ABYSS_RANKING_PLAYERS> newlyCalculated;
  		newlyCalculated = generatePacketsForRace(race);
  		players.remove(race);
  		players.put(race, newlyCalculated);
  	}
  
  	private List<SM_ABYSS_RANKING_PLAYERS> generatePacketsForRace(Race race) {
  		// players orderd by ap
  		ArrayList<AbyssRankingResult> list = getDAO().getAbyssRankingPlayers(race, RankingConfig.TOP_RANKING_MAX_OFFLINE_DAYS);
  		int page = 1;
  		List<SM_ABYSS_RANKING_PLAYERS> playerPackets = new ArrayList<SM_ABYSS_RANKING_PLAYERS>();
  		for (int i = 0; i < list.size(); i += 44) {
  			if (list.size() > i + 44) {
  				playerPackets.add(new SM_ABYSS_RANKING_PLAYERS(lastUpdate, list.subList(i, i + 44), race, page, false));
  			}
  			else {
  				playerPackets.add(new SM_ABYSS_RANKING_PLAYERS(lastUpdate, list.subList(i, list.size()), race, page, true));
  			}
  			page++;
  		}
  		return playerPackets;
  	}
  
  	/**
  	 * @return all players
  	 */
  	public List<SM_ABYSS_RANKING_PLAYERS> getPlayers(Race race) {
  		return players.get(race);
  	}
  
  	/**
  	 * @return all legions
  	 */
  	public SM_ABYSS_RANKING_LEGIONS getLegions(Race race) {
  		return legions.get(race);
  	}
  
  	/**
  	 * @return the lastUpdate
  	 */
  	public int getLastUpdate() {
  		return lastUpdate;
  	}
  
  	private AbyssRankDAO getDAO() {
  		return DAOManager.getDAO(AbyssRankDAO.class);
  	}
  
  	public static final AbyssRankingCache getInstance() {
  		return SingletonHolder.INSTANCE;
  	}
  
  	private static class SingletonHolder {
  
  		protected static final AbyssRankingCache INSTANCE = new AbyssRankingCache();
  	}
  }
  