package javastory.channel.shops;
import java.lang.ref.WeakReference;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.collect.Lists;
import javastory.channel.ChannelCharacter;
import javastory.channel.maps.AbstractGameMapObject;
import javastory.channel.packet.PlayerShopPacket;
import javastory.db.Database;
import javastory.game.Equip;
import javastory.game.Item;
import javastory.game.ItemType;
import javastory.io.GamePacket;
public abstract class AbstractPlayerShop extends AbstractGameMapObject implements PlayerShop {
private boolean open;
private final String ownerName, des;
private final int ownerId, owneraccount, itemId;
private final AtomicInteger meso = new AtomicInteger(0);
protected WeakReference[] visitors = new WeakReference[3];
protected List<PlayerShopItem> items = Lists.newLinkedList();
public AbstractPlayerShop(final ChannelCharacter owner, final int itemId, final String desc) {
this.setPosition(owner.getPosition());
this.ownerName = owner.getName();
this.ownerId = owner.getId();
this.owneraccount = owner.getAccountId();
this.itemId = itemId;
this.des = desc;
this.open = false;
}
@Override
public void broadcastToVisitors(final GamePacket packet) {
this.broadcastToVisitors(packet, true);
}
public void broadcastToVisitors(final GamePacket packet, final boolean owner) {
ChannelCharacter visitor;
for (int i = 0; i < 3; i++) {
visitor = (ChannelCharacter) this.visitors[i].get();
if (visitor != null) {
visitor.getClient().write(packet);
}
}
if (this.getShopType() == 2 && owner) {
((GenericPlayerStore) this).getMCOwner().getClient().write(packet);
}
}
@Override
public int getMeso() {
return this.meso.get();
}
@Override
public void setMeso(final int meso) {
this.meso.set(meso);
}
public void removeVisitors() {
ChannelCharacter chr = (ChannelCharacter) this.visitors[0].get();
if (chr != null) {
this.removeVisitor(chr);
}
chr = (ChannelCharacter) this.visitors[1].get();
if (chr != null) {
this.removeVisitor(chr);
}
chr = (ChannelCharacter) this.visitors[2].get();
if (chr != null) {
this.removeVisitor(chr);
}
}
@Override
public void setOpen(final boolean open) {
this.open = open;
}
@Override
public boolean isOpen() {
return this.open;
}
public boolean saveItems() {
final Connection con = Database.getConnection();
try {
final PreparedStatement ps = con.prepareStatement("INSERT INTO hiredmerch (characterid, accountid, Mesos, time) VALUES (?, ?, ?, ?)",
Statement.RETURN_GENERATED_KEYS);
ps.setInt(1, this.ownerId);
ps.setInt(2, this.owneraccount);
ps.setInt(3, this.meso.get());
ps.setLong(4, System.currentTimeMillis());
ps.executeUpdate();
final ResultSet rs = ps.getGeneratedKeys();
rs.next();
final int packageid = rs.getInt(1);
rs.close();
ps.close();
PreparedStatement ps2;
for (final PlayerShopItem pItems : this.items) {
if (pItems.bundles <= 0) {
continue;
}
final Item item = pItems.item;
if (item.getType() == ItemType.EQUIP) { // equips
ps2 = con
.prepareStatement("INSERT INTO hiredmerchitems (PackageId, itemid, quantity, upgradeslots, level, str, dex, `int`, luk, hp, mp, watk, matk, wdef, mdef, acc, avoid, hands, speed, jump, owner, GM_Log, flag, expiredate, ViciousHammer, itemLevel, itemEXP) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
final Equip eq = (Equip) item;
ps2.setInt(1, packageid);
ps2.setInt(2, eq.getItemId());
ps2.setInt(3, 1); // Quantity
ps2.setInt(4, eq.getUpgradeSlots());
ps2.setInt(5, eq.getLevel());
ps2.setInt(6, eq.getStr());
ps2.setInt(7, eq.getDex());
ps2.setInt(8, eq.getInt());
ps2.setInt(9, eq.getLuk());
ps2.setInt(10, eq.getHp());
ps2.setInt(11, eq.getMp());
ps2.setInt(12, eq.getWatk());
ps2.setInt(13, eq.getMatk());
ps2.setInt(14, eq.getWdef());
ps2.setInt(15, eq.getMdef());
ps2.setInt(16, eq.getAcc());
ps2.setInt(17, eq.getAvoid());
ps2.setInt(18, eq.getHands());
ps2.setInt(19, eq.getSpeed());
ps2.setInt(20, eq.getJump());
ps2.setString(21, eq.getOwner());
ps2.setString(22, eq.getGMLog());
ps2.setInt(23, eq.getFlag());
ps2.setLong(24, eq.getExpiration());
ps2.setInt(25, eq.getViciousHammer());
ps2.setInt(26, eq.getItemLevel());
ps2.setInt(27, eq.getItemEXP());
} else {
ps2 = con
.prepareStatement("INSERT INTO hiredmerchitems (PackageId, itemid, quantity, owner, GM_Log, flag, expiredate) VALUES (?, ?, ?, ?, ?, ?, ?)");
ps2.setInt(1, packageid);
ps2.setInt(2, item.getItemId());
ps2.setInt(3, pItems.bundles * item.getQuantity());
ps2.setString(4, item.getOwner());
ps2.setString(5, item.getGMLog());
ps2.setInt(6, item.getFlag());
ps2.setLong(7, item.getExpiration());
}
ps2.execute();
ps2.close();
}
return true;
} catch (final SQLException se) {
se.printStackTrace();
}
return false;
}
public ChannelCharacter getVisitor(final int num) {
if (1 <= num && num <= 3) {
return (ChannelCharacter) this.visitors[num - 1].get();
}
return null;
}
@Override
public void addVisitor(final ChannelCharacter visitor) {
final int i = this.getFreeSlot();
if (i > -1) {
this.broadcastToVisitors(PlayerShopPacket.shopVisitorAdd(visitor, i));
this.visitors[i - 1] = new WeakReference<ChannelCharacter>(visitor);
if (i == 3) {
if (this.getShopType() == 1) {
final HiredMerchantStore hiredMerchant = (HiredMerchantStore) this;
hiredMerchant.getMap().broadcastMessage(PlayerShopPacket.updateHiredMerchant(hiredMerchant));
} else {
final ChannelCharacter owner = ((GenericPlayerStore) this).getMCOwner();
owner.getMap().broadcastMessage(PlayerShopPacket.sendPlayerShopBox(owner));
}
}
}
}
@Override
public void removeVisitor(final ChannelCharacter visitor) {
final byte slot = this.getVisitorSlot(visitor);
final boolean shouldUpdate = this.getFreeSlot() == -1;
if (slot != -1) {
this.broadcastToVisitors(PlayerShopPacket.shopVisitorLeave(slot));
this.visitors[slot - 1] = new WeakReference<ChannelCharacter>(null);
if (shouldUpdate) {
if (this.getShopType() == 1) {
final HiredMerchantStore hiredMerchant = (HiredMerchantStore) this;
hiredMerchant.getMap().broadcastMessage(PlayerShopPacket.updateHiredMerchant(hiredMerchant));
} else {
final ChannelCharacter owner = ((GenericPlayerStore) this).getMCOwner();
owner.getMap().broadcastMessage(PlayerShopPacket.sendPlayerShopBox(owner));
}
}
}
}
@Override
public byte getVisitorSlot(final ChannelCharacter visitor) {
ChannelCharacter chr;
for (byte i = 1; i <= 3; i++) {
chr = (ChannelCharacter) this.visitors[i - 1].get();
if (chr == visitor) {
return i;
}
}
return -1;
}
@Override
public void removeAllVisitors(final int error, final int type) {
for (int i = 1; i <= 3; i++) {
final ChannelCharacter visitor = this.getVisitor(i);
if (visitor != null) {
if (type != -1) {
visitor.getClient().write(PlayerShopPacket.shopErrorMessage(error, type));
}
visitor.setPlayerShop(null);
this.visitors[i - 1] = new WeakReference<>(null);
}
}
}
@Override
public String getOwnerName() {
return this.ownerName;
}
@Override
public int getOwnerId() {
return this.ownerId;
}
@Override
public int getOwnerAccountId() {
return this.owneraccount;
}
@Override
public String getDescription() {
if (this.des == null) {
return "";
}
return this.des;
}
@Override
public List<ChannelCharacter> getVisitors() {
final List<ChannelCharacter> chars = Lists.newLinkedList();
ChannelCharacter visitor;
for (int i = 1; i <= 3; i++) {
visitor = (ChannelCharacter) this.visitors[i - 1].get();
if (visitor != null) {
chars.add(visitor);
}
}
return chars;
}
@Override
public List<PlayerShopItem> getItems() {
return this.items;
}
@Override
public void addItem(final PlayerShopItem item) {
this.items.add(item);
}
@Override
public boolean removeItem(final int item) {
return false;
}
@Override
public void removeFromSlot(final int slot) {
this.items.remove(slot);
}
@Override
public byte getFreeSlot() {
for (byte i = 1; i <= 3; i++) {
if (this.visitors[i].get() == null) {
return i;
}
}
return -1;
}
@Override
public int getItemId() {
return this.itemId;
}
@Override
public boolean isOwner(final ChannelCharacter chr) {
return chr.getId() == this.ownerId && chr.getName().equals(this.ownerName);
}
}