/*
* This program 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.
*
* This program 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
* this program. If not, see .
*/
package com.l2jserver.gameserver.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.ItemTable;
import com.l2jserver.gameserver.templates.item.L2Item;
import javolution.util.FastMap;
/**
* This class ...
*
* @version $Revision: 1.4.2.1.2.5 $ $Date: 2005/03/27 15:29:33 $
*/
public class L2TradeList
{
private Map _items;
private int _listId;
private String _buystorename, _sellstorename;
private boolean _hasLimitedStockItem;
private String _npcId;
public L2TradeList(int listId)
{
_items = new FastMap();
_listId = listId;
}
public void setNpcId(String id)
{
_npcId = id;
}
public String getNpcId()
{
return _npcId;
}
public void addItem(L2TradeItem item)
{
_items.put(item.getItemId(), item);
if (item.hasLimitedStock())
{
this.setHasLimitedStockItem(true);
}
}
public void replaceItem(int itemID, long price)
{
L2TradeItem item = _items.get(itemID);
if (item != null)
{
item.setPrice(price);
}
}
public void removeItem(int itemID)
{
_items.remove(itemID);
}
/**
* @return Returns the listId.
*/
public int getListId()
{
return _listId;
}
/**
* @param hasLimitedStockItem The hasLimitedStockItem to set.
*/
public void setHasLimitedStockItem(boolean hasLimitedStockItem)
{
_hasLimitedStockItem = hasLimitedStockItem;
}
/**
* @return Returns the hasLimitedStockItem.
*/
public boolean hasLimitedStockItem()
{
return _hasLimitedStockItem;
}
public void setSellStoreName(String name)
{
_sellstorename = name;
}
public String getSellStoreName()
{
return _sellstorename;
}
public void setBuyStoreName(String name)
{
_buystorename = name;
}
public String getBuyStoreName()
{
return _buystorename;
}
/**
* @return Returns the items.
*/
public Collection getItems()
{
return _items.values();
}
public List getItems(int start, int end)
{
List list = new LinkedList();
list.addAll(_items.values());
return list.subList(start, end);
}
public long getPriceForItemId(int itemId)
{
L2TradeItem item = _items.get(itemId);
if (item != null)
{
return item.getPrice();
}
return -1;
}
public L2TradeItem getItemById(int itemId)
{
return _items.get(itemId);
}
/*
public boolean countDecrease(int itemId)
{
L2TradeItem item = _items.get(itemId);
if (item != null)
{
return item.hasLimitedStock();
}
return false;
}*/
public boolean containsItemId(int itemId)
{
return _items.containsKey(itemId);
}
/**
* Itens representation for trade lists
*
* @author KenM
*/
public static class L2TradeItem
{
private static final Logger _log = Logger.getLogger(L2TradeItem.class.getName());
private final int _listId;
private final int _itemId;
private final L2Item _template;
private long _price;
// count related
private AtomicLong _currentCount = new AtomicLong();
private long _maxCount = -1;
private long _restoreDelay;
private long _nextRestoreTime;
public L2TradeItem(int listId, int itemId)
{
_listId = listId;
_itemId = itemId;
_template = ItemTable.getInstance().getTemplate(itemId);
}
/**
* @return Returns the itemId.
*/
public int getItemId()
{
return _itemId;
}
/**
* @param price The price to set.
*/
public void setPrice(long price)
{
_price = price;
}
/**
* @return Returns the price.
*/
public long getPrice()
{
return _price;
}
public L2Item getTemplate()
{
return _template;
}
/**
* @param currentCount The currentCount to set.
*/
public void setCurrentCount(long currentCount)
{
_currentCount.set(currentCount);
}
public boolean decreaseCount(long val)
{
return _currentCount.addAndGet(-val) >= 0;
}
/**
* @return Returns the currentCount.
*/
public long getCurrentCount()
{
if (this.hasLimitedStock() && this.isPendingStockUpdate())
{
this.restoreInitialCount();
}
long ret = _currentCount.get();
return ret > 0 ? ret : 0;
}
public boolean isPendingStockUpdate()
{
return System.currentTimeMillis() >= _nextRestoreTime;
}
public void restoreInitialCount()
{
this.setCurrentCount(this.getMaxCount());
_nextRestoreTime = _nextRestoreTime + this.getRestoreDelay();
// consume until next update is on future
if (this.isPendingStockUpdate() && this.getRestoreDelay() > 0)
{
_nextRestoreTime = System.currentTimeMillis() + this.getRestoreDelay();
}
// exec asynchronously
try
{
ThreadPoolManager.getInstance().executeTask(new TimerSave());
}
catch (RejectedExecutionException e)
{
// during shutdown executeTask() failed
saveDataTimer();
}
}
/**
* @param maxCount The maxCount to set.
*/
public void setMaxCount(long maxCount)
{
_maxCount = maxCount;
}
/**
* @return Returns the maxCount.
*/
public long getMaxCount()
{
return _maxCount;
}
public boolean hasLimitedStock()
{
return this.getMaxCount() > -1;
}
/**
* @param restoreDelay The restoreDelay to set (in hours)
*/
public void setRestoreDelay(long restoreDelay)
{
_restoreDelay = restoreDelay * 60 * 60 * 1000;
}
/**
* @return Returns the restoreDelay (in milis)
*/
public long getRestoreDelay()
{
return _restoreDelay;
}
/**
* For resuming when server loads
* @param nextRestoreTime The nextRestoreTime to set.
*/
public void setNextRestoreTime(long nextRestoreTime)
{
_nextRestoreTime = nextRestoreTime;
}
/**
* @return Returns the nextRestoreTime.
*/
public long getNextRestoreTime()
{
return _nextRestoreTime;
}
class TimerSave implements Runnable
{
/**
* @see java.lang.Runnable#run()
*/
public void run()
{
L2TradeItem.this.saveDataTimer();
}
}
protected void saveDataTimer()
{
Connection con = null;
try
{
con = L2DatabaseFactory.getInstance().getConnection();
PreparedStatement statement = con.prepareStatement("UPDATE merchant_buylists SET savetimer =? WHERE shop_id =? and item_id =?");
statement.setLong(1, _nextRestoreTime);
statement.setInt(2, _listId);
statement.setInt(3, _itemId);
statement.executeUpdate();
statement.close();
}
catch (Exception e)
{
_log.log(Level.SEVERE, "L2TradeItem: Could not update Timer save in Buylist");
}
finally
{
L2DatabaseFactory.close(con);
}
}
}
}