package org.black_ixx.bossshop.sale;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.black_ixx.bossshop.BossShop;
import org.black_ixx.bossshop.command.CommandSale;
import org.black_ixx.bossshop.core.BSBuy;
import org.black_ixx.bossshop.core.BSEnums;
import org.black_ixx.bossshop.core.BSShop;
import org.black_ixx.bossshop.core.BSShopManager;
import org.black_ixx.bossshop.nbt.NBTEditManager;
import org.black_ixx.bossshop.points.PointsManager;
import org.black_ixx.bossshop.core.BSEnums.BSBuyType;
import org.black_ixx.bossshop.managers.DefaultCreator;
import org.black_ixx.bossshop.managers.ItemNameManager;
import org.black_ixx.bossshop.managers.LangManager;
import org.black_ixx.bossshop.managers.WorthHandler;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

import cc.util.bossshop.FBukkit;
import cc.util.bossshop.config.CommentedYamlConfig;
import cc.util.bossshop.pluginmodel.INeedConfig;

/**
 * 玩家寄售系统
 * @author 聪聪
 *
 */
public class SaleManager implements INeedConfig{
    
    public static final String CFG_MAIN="SaleSystem";
    public static final String CFG_ShopBaseName="ShopBaseName";
    public static final String CFG_ShopSize="ShopSize";
    public static final String CFG_ShopMaxNumb="ShopMaxNumb";
    public static final String CFG_SaleTime="SaleTime";
    public static final String CFG_MoneyItem="MoneyItem";
    public static final String CFG_MoneyPoundage="MoneyPoundage";
    public static final String CFG_PointsItem="PointsItem";
    public static final String CFG_PointsPoundage="PointsPoundage";
    public static final String CFG_PerOneSaleLimit="PerOneSaleLimit";
    public static final String CFG_UnsaleCost="UnsaleCost";
    public static final String CFG_UnsaleCount="UnsaleCount";
    public static final String CFG_SaleItemName="SaleItemName";
    public static final String CFG_SaleItemLore="SaleItemLore";
    private static final Pattern PATTERN = Pattern.compile("[%]([^%]+)[%]");
    private final static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");
    private BossShop mPlugin;
    private int mSaleTime=86400;
    private int mPerOneSaleLimit=1;
    private int mMoneyItem=9;
    private int mPointsItem=10;
    private int mShopMaxNumb=2;
    private int mShopSize=54;
    private int mMoneyPoundage=5;
    private int mPointsPoundage=5;
    private int mUnsaleCost=1000;
    private int mUnsaleCount=3;
    private String mShopBaseName="SYSTEM_SALE";
    private String mSaleItemName="&2寄售: %bs_sale_item_sigle_count% %bs_sale_item_name%";
    private final ArrayList<String> mSaleItemLore;
    private final HashMap<BSBuyType,String> mLang=new HashMap<>();
    
    public SaleManager(BossShop pplugin){
        this.mPlugin=pplugin;
        this.mSaleItemLore=new ArrayList<>();
        this.mSaleItemLore.add("&2寄售编号: %bs_sale_item_id%");
        this.mSaleItemLore.add("&3寄售者: %bs_sale_owner_name%");
        this.mSaleItemLore.add("&c价格: %bs_sale_price% %bs_sale_price_type%");
        this.mPlugin.registerConfigModel(this);
    }
    
    @Override
    public void setConfig(){
        //配置文件
        CommentedYamlConfig tConfig=this.mPlugin.getConfigManager().getConfig();
        ConfigurationSection sec=tConfig.getConfigurationSection(CFG_MAIN);
        if(sec==null) sec=tConfig.createSection(CFG_MAIN);
        this.mShopBaseName=sec.getString(CFG_ShopBaseName);
        this.mMoneyItem=sec.getInt(CFG_MoneyItem,0);
        if(this.mMoneyItem==0||org.bukkit.Material.getMaterial(this.mMoneyItem)==null){
            this.mMoneyItem=9;
            sec.set(CFG_MoneyItem,this.mMoneyItem);
        }
        this.mPointsItem=sec.getInt(CFG_PointsItem,0);
        if(this.mPointsItem==0||org.bukkit.Material.getMaterial(this.mPointsItem)==null){
            this.mPointsItem=10;
            sec.set(CFG_PointsItem,this.mPointsItem);
        }
        this.mSaleTime=sec.getInt(CFG_SaleTime,this.mSaleTime);
        this.mPerOneSaleLimit=sec.getInt(CFG_PerOneSaleLimit,this.mPerOneSaleLimit);
        this.mShopSize=sec.getInt(CFG_ShopSize,this.mShopSize);
        this.mShopMaxNumb=sec.getInt(CFG_ShopSize,this.mShopMaxNumb);
        this.mMoneyPoundage=sec.getInt(CFG_MoneyPoundage,this.mMoneyPoundage);
        this.mPointsPoundage=sec.getInt(CFG_PointsPoundage,this.mPointsPoundage);
        this.mUnsaleCount=sec.getInt(CFG_UnsaleCount,this.mUnsaleCount);
        this.mUnsaleCost=sec.getInt(CFG_UnsaleCost,this.mUnsaleCost);
        this.mSaleItemName=sec.getString(CFG_SaleItemName,this.mSaleItemName);
        List<String> list=sec.getStringList(CFG_SaleItemLore);
        if(list!=null&&!list.isEmpty()){
            this.mSaleItemLore.clear();
            this.mSaleItemLore.addAll(list);
        }
        this.mPlugin.getConfigManager().saveConfig();
        //语言文件
        LangManager tLang=this.mPlugin.getLangManager();
        this.mLang.clear();
        this.mLang.put(BSBuyType.Money,tLang.get("Word.Money"));
        this.mLang.put(BSBuyType.Points,tLang.get("Word.Points"));
        this.mLang.put(BSBuyType.Item,tLang.get("Word.Item"));
    }
            
    /**
     * 给予上架物品出售后的收获,如果所有者在线,通知所有者物品被购买
     * @param pPlayer 玩家
     * @param pBuy 售出的物品
     */
    public void giveSaleReward(BSBuy pBuy){
        if(pBuy==null) return;
        if(!pBuy.hasOwner()) return;
        Player player=Bukkit.getPlayer(pBuy.getOwner());
        if(player==null){
            this.mPlugin.warn(C("CFG.UnableFoundSaleOwner"));
            return;
        }
        int numb=0;
        WorthHandler wHandler=this.mPlugin.getManager(WorthHandler.class);
        switch(pBuy.getPriceType()){
        case Money:
            numb=SaleManager.getActualySaleReward((Integer)pBuy.getPrice(),this.mMoneyPoundage);
            wHandler.giveRewardMoney(player,numb);
            break;
        case Points:
            numb=SaleManager.getActualySaleReward((Integer)pBuy.getPrice(),this.mPointsPoundage);
            wHandler.giveRewardPoints(player,numb);
            break;
        default:
            this.mPlugin.warn(C("CFG.UnknowSalePriceType"));
            break;
        }
        this.mPlugin.send(player,C("Cmd.YouSaleHasSellOne")+"["+pBuy.getName()+"]");
    }
    
    private String C(String pNode){
        return this.mPlugin.getLangManager().getNode(pNode);
    }

    /**
     * 采用四舍五入发计算收取手续费后的收入
     * @param pNowReward
     * @param pPoundage
     * @return
     */
    public static int getActualySaleReward(int pNowReward,int pPoundage){
        if(pPoundage<0||pPoundage>=100) return pNowReward;
        int t=pNowReward*(100-pPoundage);
        int unSolve=t%100;
        if(unSolve==0){
            return t/100;
        }else{
            return t/100+(unSolve<50?0:1);
        }
    }
    
    public int getShopMaxCount(){
        return this.mShopMaxNumb;
    }
    
    public String getShopBaseName(){
        return this.mShopBaseName;
    }
    
    public int getUnsaleCount(){
        return this.mUnsaleCount;
    }
    
    public int getUnSaleCost(){
        return this.mUnsaleCost;
    }
    
    public BSBuy getSaleItem(String pName){
        for(int i=1;i<this.mShopMaxNumb;i++){
            BSShop tShop=this.mPlugin.getManager(BSShopManager.class).getShop(this.mShopBaseName+i);
            if(tShop==null) continue;
            BSBuy tBuy=tShop.getShopItem(pName);
            if(tBuy==null||!tBuy.hasOwner()) continue;
            else return tBuy;
        }
        return null;
    }
    
    /**
     * 获取所有在寄售物品的编号
     */
    public ArrayList<String> getSaleItemsName(){
        return this.getSaleItemsName(null);
    }
    
    /**
     * 获取指定玩家所有在寄售物品编号
     * <p>如果玩家未null,将返回所有在寄售物品编号</p>
     * @param pPlayer 玩家,可以为null
     */
    public ArrayList<String> getSaleItemsName(Player pPlayer){
        ArrayList<String> allSale=new ArrayList<>();
        for(int i=1;i<this.mShopMaxNumb;i++){
            BSShop tShop=this.mPlugin.getManager(BSShopManager.class).getShop(this.mShopBaseName+i);
            if(tShop==null) continue;
            for(BSBuy sBuy : tShop.getItems().values()){
                if(!sBuy.hasOwner()) continue;
                if(pPlayer==null||sBuy.getOwner().equals(pPlayer.getUniqueId()))
                    allSale.add(sBuy.getName());
            }
        }
        return allSale;
    }
    
    /**
     * 获取玩家寄售数量
     * @param pName 玩家名
     */
    public int getForSaleNumb(Player pPlayer){
        int count=0;
        for(int i=1;i<this.mShopMaxNumb;i++){
            BSShop tShop=this.mPlugin.getManager(BSShopManager.class).getShop(this.mShopBaseName+i);
            if(tShop==null) continue;
            for(BSBuy sbuy : tShop.getItems().values())
                if(sbuy.hasOwner()&&sbuy.getOwner().equals(pPlayer.getUniqueId())) count++;
        }
        return count;
    }
    
    /**
     * 获取下一个可用的商店,并同时获取商店放置位置
     * <p>如果shop为null,说明无可用的商店用于上架</p>
     */
    public SaleParameter getAvailableShop(SaleParameter pParam){
        BSShop taregt_shop=null;
        BSShopManager shopMan=this.mPlugin.getManager(BSShopManager.class);
        BSShop frontShop=shopMan.getShop(this.mPlugin.getConfigManager().getMainShop());
        int target_loc=0,i;
        for(i=1;i<=this.mShopMaxNumb;i++){
            String tShopname=this.mShopBaseName+i;
            taregt_shop=shopMan.getShop(tShopname);
            if(taregt_shop!=null){
                frontShop=taregt_shop;
                target_loc=taregt_shop.getNextAvailableLoc();
                if(target_loc<=0||target_loc>this.mShopMaxNumb-2) continue;
                break;
            }else{
                taregt_shop=this.createShop(frontShop,tShopname,i);
                target_loc=1;
                break;
            }
        }
        if(i<=this.mShopMaxNumb){
            pParam.shop=taregt_shop;
            pParam.location=target_loc;
        }
        return pParam;
    }
    
    /**
     * 创建一个寄售商店
     * @param pShopname 商店名
     * @param pIndex 寄售商店索引
     * @return 创建好的商店
     */
    private BSShop createShop(BSShop pFrontShop,String pShopname,int pIndex){
        File tFile=new File(this.mPlugin.getDataFolder().getAbsolutePath()+"/shops/"+pShopname+".yml");
        CommentedYamlConfig tConfig=new CommentedYamlConfig();
        tConfig.loadFromFile(tFile);
        String tname=C("Word.SaleShop")+" "+pIndex;
        DefaultCreator.setSettings(tConfig,tname,tname);
        //设置返回键
        if(pIndex==1){
            String tMainShop=this.mPlugin.getConfigManager().getMainShop();
            DefaultCreator.setGuidItem(tConfig,this.mShopSize-1,348,tMainShop,"RETURN_TO_FROUNT");
        }else{
            DefaultCreator.setGuidItem(tConfig,this.mShopSize-1,348,this.mShopBaseName+(pIndex-1),"RETURN_TO_FROUNT");
            if(pFrontShop!=null){
                CommentedYamlConfig tFrontConfig=pFrontShop.getConfig();
                DefaultCreator.setGuidItem(tFrontConfig,this.mShopSize,331,pShopname,tname,"GOTO_TO_NEXT");
                pFrontShop.saveConfig();
                pFrontShop.reloadConfig();
            }
        }
        //设置下一个按键
        BSShopManager shopMan=this.mPlugin.getManager(BSShopManager.class);
        if(pIndex!=this.mShopMaxNumb&&shopMan.getShop("this.mShopBaseName+(pIndex+1)")!=null)
            DefaultCreator.setGuidItem(tConfig,this.mShopSize,331,this.mShopBaseName+(pIndex+1),"GOTO_TO_NEXT");
        tConfig.saveToFile(tFile);
        BSShop tshop=new BSShop(this.mPlugin,pShopname+".yml",pShopname);
        shopMan.addShop(tshop);
        return tshop;
    }
    
    /**
     * 物品上架接口
     * @param player 命令发送人 
     * @param args 参数
     * @return 是否成功上架,错误消息会立刻反馈给玩家
     */
    public boolean sale(Player player,String[] args){
        if(args.length!=5) return this.getHelp(player);
        //检查寄售上限
        if(this.getForSaleNumb(player)>=this.mPerOneSaleLimit&&!player.hasPermission("BossShop.sale.unlimited"))
            return this.mPlugin.send(player,C("Cmd.SaleReachPreOneLimit"));
        SaleParameter param=new SaleParameter();
        //获取可用的商店
        this.getAvailableShop(param);
        if(param.shop==null)
            return this.mPlugin.send(player,C("Cmd.SaleShopIsFull"));
        //格式化参数
        this.formatSale(param,player,args);
        if(param.errorInfo!=null)
            return this.mPlugin.send(player,ChatColor.RED+param.errorInfo);
        ItemStack item=player.getItemInHand();
        if(param.saleType==BSBuyType.Item&&(item==null||item.getTypeId()==0))
            return this.mPlugin.send(player,C("Cmd.YouShouldTakeItemInHand"));
        //是否有足够的资本.此处会检查物品是否可以堆叠
        if(!this.enough(param)) return false;
        //查找可用的物品名字节点
        ConfigurationSection sec_item_main=param.shop.getConfig().getConfigurationSection("shop");
        ConfigurationSection sec_item=null;
        long time=System.currentTimeMillis()/1000;
        String sec_item_name=param.owner.getName()+"_"+time;
        if(sec_item_main!=null){
            do{
                sec_item_name=param.owner.getName()+"_"+time;
                time++;
            }while(sec_item_main.contains(sec_item_name));
            sec_item=sec_item_main.createSection(sec_item_name);
        }else sec_item=param.shop.getConfig().createSection("shop."+sec_item_name);
        param.mID=sec_item_name;
        //替换文本变量
        this.replaceInfoParam(param);
        //设置上架物品到文件,并同时收取价格
        //设置菜单物品到上架参数中,用于发送全服公告
        this.setConfigSection(sec_item,param);
        this.mPlugin.send(player,C("Cmd.ForSaleSuccessAndTisID")+sec_item_name);
        //全服公告
        this.sendSaleAnnoun(param);
        return true;
    }
    
    /**
     * 发送全服公告
     */
    private void sendSaleAnnoun(SaleParameter param){
        if(!param.owner.hasPermission("BossShop.sale.announce.other"))
            return;
        BSBuy saleBuy=param.shop.getShopItem(param.location-1);
        for(Player sPlayer : FBukkit.getOnlinePlayers()){
            saleBuy.getPersonalChatMenuItem(sPlayer,param.owner).sendToPlayer(sPlayer);
        }
    }
    
    /**
     * 根据上架参数,添加物品到商店配置文件中,并同时收取价格
     * @param sec 要设置的节点
     * @param param 上架参数
     * @param pos 背包位置
     */
    private void setConfigSection(ConfigurationSection sec,SaleParameter param){
        ArrayList<String> item_info=new ArrayList<>();
        String lore_prefix="&2";
        for(String sStr : param.mLore) lore_prefix+="#"+sStr;
        item_info.add("name:"+param.mDisplayName);
        item_info.add("lore:"+lore_prefix);
        ItemStack item=new ItemStack(Material.STONE);
        ItemMeta meta=item.getItemMeta();
        WorthHandler wHandler=this.mPlugin.getManager(WorthHandler.class);
        switch(param.saleType){
        case Money:
            wHandler.takeMoney(param.owner,param.singleNumb*param.partNumb);
            meta.setDisplayName(param.singleNumb+" "+C("Word.Money"));
            item_info.add("id:"+this.mMoneyItem);
            item.setTypeId(this.mMoneyItem);
            item_info.add("amount:1");
            sec.set("MenuItem",item_info);
            sec.set("Reward",param.singleNumb);
            break;
        case Points:
            wHandler.takePoints(param.owner,param.singleNumb*param.partNumb);
            meta.setDisplayName(param.singleNumb+" "+C("Word.Points"));
            item_info.add("id:"+this.mPointsItem);
            item_info.add("amount:1");
            sec.set("MenuItem",item_info);
            sec.set("Reward",param.singleNumb);
            break;
        case Item:
            item=param.owner.getItemInHand().clone();
            ItemStack itemTake=item.clone();
            itemTake.setAmount(param.singleNumb*param.partNumb);
            ArrayList<ItemStack> listItem=new ArrayList<>();
            listItem.add(itemTake);
            wHandler.takeItems(param.owner,listItem);
            item_info.add("type:"+item.getType().name());
            item_info.add("durability:"+item.getDurability());
            item_info.add("amount:"+param.singleNumb);
            String nbtlabel=this.mPlugin.getManager(NBTEditManager.class).addItemNBTToStock(item,true);
            if(nbtlabel!=null) item_info.add("nbt:"+nbtlabel);
            sec.set("MenuItem",item_info);
            item_info=new ArrayList<>();
            if(item.getItemMeta().hasDisplayName()) item_info.add("name:"+item.getItemMeta().getDisplayName());
            item_info.add("id:"+item.getTypeId());
            item_info.add("durability:"+item.getDurability());
            item_info.add("amount:"+param.singleNumb);
            if(nbtlabel!=null) item_info.add("nbt:"+nbtlabel);
            sec.set("Reward",item_info);
            break;
        default: break;
        }
        List<String> tLores=meta.getLore();
        if(tLores==null) tLores=new ArrayList<String>();
        tLores.add("&2"+C("Word.SaleID")+":"+param.mID);
        Date date=new Date(System.currentTimeMillis()+this.mSaleTime*1000);
        sec.set("TimeLimit.stop",sdf.format(date));
        sec.set("HideItemFlag",this.mPlugin.getConfigManager().getHideItemFlag());
        sec.set("HideNotTime",true);
        sec.set("NumberLimit",param.partNumb);
        tLores.add("&2"+C("Word.PartNumb")+":"+param.partNumb);
        sec.set("HideNoStock",true);
        sec.set("InventoryLocation",param.location);
        sec.set("RewardType",param.saleType.toString());
        sec.set("PriceType",param.priceType.toString());
        sec.set("Price",param.price);
        tLores.add("&2"+C("Word.Price")+":"+param.price+(param.priceType==BSBuyType.Money?C("Word.Money"):C("Word.Points")));
        sec.set("Message",C("Word.YouBought")+param.mDisplayName);
        sec.set("Owner",param.owner.getUniqueId().toString());
        sec.set("OwnerOnlyForLook",param.owner.getName());
        meta.setLore(tLores);
        item.setItemMeta(meta);
        param.shop.saveConfig();
        param.shop.reloadConfig();
    }
        
    /**
     * 玩家是否有足够的资本上架,如果不足会立刻发送错误消息给玩家
     */
    private boolean enough(SaleParameter param){
        WorthHandler wHandler=this.mPlugin.getManager(WorthHandler.class);
        switch(param.saleType){
        case Money:
            return wHandler.hasMoney(param.owner,param.singleNumb*param.partNumb);
        case Points:
            return wHandler.hasPoints(param.owner,param.singleNumb*param.partNumb);
        case Item:
            ItemStack item=param.owner.getItemInHand().clone();
            int maxCount=item.getMaxStackSize();
            if(maxCount!=-1&&maxCount<param.singleNumb){
                this.mPlugin.send(param.owner,C("Main.ItemCannotPileMoreThan")+maxCount);
                return false;
            }
            item.setAmount(param.singleNumb*param.partNumb);
            ArrayList<ItemStack> items=new ArrayList<>();
            items.add(item);
            return wHandler.hasItems(param.owner,items);
        default:
            break;
        }
        return false;
    }
    
    /**
     * 从命令参数中生成上架物品的参数
     * <p>如果参数错误,错误消息存储在SaleParameter.errorInfo中,
     * 如果SaleParameter.errorInfo为空说明没有错误</p>
     * @param pPlayer 玩家
     * @param args 参数
     * @return 上架物品参数
     */
    private boolean formatSale(SaleParameter pParam,Player pPlayer,String[] args){
        pParam.owner=pPlayer;
        if(!this.handleGoodsTypeInput(pParam,pPlayer,args[0])) return false;
        //单次的数量
        if(!this.handleSingleNumbInput(pParam,pPlayer,args[1])) return false;
        //几份
        if(!this.handlePartNumbInput(pParam,pPlayer,args[2])) return false;
        //价格类型
        if(!this.handlePriceTypeInput(pParam,pPlayer,args[3])) return false;
        //价格
        if(!this.handlePriceInput(pParam,pPlayer,args[4])) return false;
        return true;
    }
    
    protected boolean handleGoodsTypeInput(SaleParameter pParam,Player pPlayer,String pInput){
        pParam.saleType=BSEnums.getBSBuyType(pInput);
        if(pParam.saleType==null){
            pParam.errorInfo=C("Cmd.UnknowSaleItemType")+"["+pInput+"]";
            return false;
        }
        if(pParam.saleType!=BSBuyType.Item&&pParam.saleType!=BSBuyType.Money&&pParam.saleType!=BSBuyType.Points){
            pParam.errorInfo=C("Cmd.UnsupportSaleItemType")+"["+pParam.saleType.toString()+"]";
            return false;
        }
        return true;
    }
    
    protected boolean handleSingleNumbInput(SaleParameter pParam,Player pPlayer,String pInput){
        try{
            pParam.singleNumb=Integer.parseInt(pInput);
        }catch(NumberFormatException nfexp){
            pParam.errorInfo=ChatColor.RED+C("Word.SigleNumb")+" "+C("Cmd.MustBeNumb");
            return false;
        }
        if(pParam.singleNumb<=0){
            pParam.errorInfo=ChatColor.RED+C("Word.SigleNumb")+" "+C("Cmd.MustAboveZero");
            return false;
        }
        return true;
    }
    
    protected boolean handlePartNumbInput(SaleParameter pParam,Player pPlayer,String pInput){
        try{
            pParam.partNumb=Integer.parseInt(pInput);
        }catch(NumberFormatException nfexp){
            pParam.errorInfo=ChatColor.RED+C("Word.PartNumb")+" "+C("Cmd.MustBeNumb");
            return false;
        }
        if(pParam.partNumb<=0){
            pParam.errorInfo=ChatColor.RED+C("Word.PartNumb")+" "+C("Cmd.MustAboveZero");
            return false;
        }
        return true;
    }
    
    /**
     * 处理价格类型输入
     * <p>
     * 处理失败,失败结果会存储在{@link SaleParameter#errorInfo}中<br />
     * 函数内同时会处理寄售类型和价格类型相同的情况
     * </p>
     * @param pParam 已经处理的参数
     * @param pPlayer 输入者
     * @param pInput 输入字符
     * @return 是否处理成功
     */
    protected boolean handlePriceTypeInput(SaleParameter pParam,Player pPlayer,String pInput){
        pParam.priceType=BSEnums.getBSBuyType(pInput);
        if(pParam.priceType==null){
            pParam.errorInfo=C("Cmd.UnknowPriceType")+"["+pInput+"]";
            return false;
        }
        if(pParam.priceType!=BSBuyType.Money&&pParam.priceType!=BSBuyType.Points){
            pParam.errorInfo=C("Cmd.UnsupportPriceType")+"["+pParam.priceType.name()+"]";
            return false;
        }
        //点券插件是否启用
        if(pParam.priceType==BSBuyType.Points){
            if(this.mPlugin.getManager(PointsManager.class)==null){
                pParam.errorInfo=C("Cmd.ServerDisablePoints");
                return false;
            }
        }
        //不允许寄售物品和价格类型相同
        if(pParam.priceType.name().equals(pParam.saleType.name())){
            pParam.errorInfo=C("Cmd.SaleItemShouldNotSameWithPrice");
            return false;
        }
        return true;
    }
    
    protected boolean handlePriceInput(SaleParameter pParam,Player pPlayer,String pInput){
        try{
            pParam.price=Integer.parseInt(pInput);
        }catch(NumberFormatException nfexp){
            pParam.errorInfo=ChatColor.RED+"<"+C("Word.Price")+">"+C("Cmd.MustBeNumb");
            return false;
        }
        if(pParam.price<=0){
            pParam.errorInfo=ChatColor.RED+"<"+C("Word.Price")+">"+C("Cmd.MustAboveZero");
            return false;
        }
        return true;
    }    

    /**
     * 上架系统命令帮助
     */
    public boolean getHelp(Player player){
        return this.mPlugin.getCommandExc().getCommand(CommandSale.class).help(player);
    }
    
    /**
     * 将寄售模板中的字符串变量替换之后放到寄售参数中
     */
    public void replaceInfoParam(SaleParameter pParam){
        pParam.mDisplayName=this.formatString(this.mSaleItemName,pParam);
        pParam.mLore=new ArrayList<>();
        for(String sStr : this.mSaleItemLore)
            pParam.mLore.add(this.formatString(sStr,pParam));
    }
    
    /**
     * 替换字符串中的变量,所有支持的变量:<br/>
     * %bs_sale_owner_name%<br/>
     * %bs_sale_item_id%<br/>
     * %bs_sale_item_sigle_count%<br/>
     * %bs_sale_item_part_count%<br/>
     * %bs_sale_item_type%<br/>
     * %bs_sale_item_name%<br/>
     * %bs_sale_price%<br/>
     * %bs_sale_price_type%<br/>
     */
    protected String formatString(String pStr,SaleParameter pSaleParam){
        Matcher tMatch=PATTERN.matcher(pStr);
        while(tMatch.find()){
            String tParam=tMatch.group(1);
            String value=tParam;
            if(tParam.equalsIgnoreCase("bs_sale_owner_name")){
                value=pSaleParam.owner.getName();
            }else if(tParam.equalsIgnoreCase("bs_sale_item_id")){
                value=pSaleParam.mID;
            }else if(tParam.equalsIgnoreCase("bs_sale_item_sigle_count")){
                value=pSaleParam.singleNumb+"";
            }else if(tParam.equalsIgnoreCase("bs_sale_item_part_count")){
                value=pSaleParam.partNumb+"";
            }else if(tParam.equalsIgnoreCase("bs_sale_item_type")){
                value=this.mLang.get(pSaleParam.saleType);
            }else if(tParam.equalsIgnoreCase("bs_sale_item_name")){
                String tName="";
                if(pSaleParam.saleType==BSBuyType.Item){
                    ItemStack tItem=pSaleParam.owner.getPlayer().getItemInHand();
                    tName=this.mPlugin.getManager(ItemNameManager.class).getDisPlayName(tItem);
                }
                else tName=this.mLang.get(pSaleParam.saleType);
                value=tName;
            }else if(tParam.equalsIgnoreCase("bs_sale_price")){
                value=pSaleParam.price+"";
            }else if(tParam.equalsIgnoreCase("bs_sale_price_type")){
                value=this.mLang.get(pSaleParam.priceType);
            }else this.mPlugin.warn(C("CFG.UnsupportSaleItemParam"));
            if(tParam!=value)
                pStr=pStr.replaceAll("%"+tParam+"%",value);
        }
        return pStr;
    }
    
}



