package com.planet_ink.coffee_mud.Abilities.Properties;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;


import java.util.*;

/* 
   Copyright 2000-2006 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class Prop_HaveResister extends Property
{
	public String ID() { return "Prop_HaveResister"; }
	public String name(){ return "Resistance due to ownership";}
	protected int canAffectCode(){return Ability.CAN_ITEMS;}
	public boolean bubbleAffect(){return true;}
    protected CharStats adjCharStats=null;
    protected Vector mask=new Vector();
    protected String maskString="";
    protected String parmString="";
    protected boolean ignoreCharStats=true;

    public static Object[][] stats={
            {new Integer(CharStats.STAT_SAVE_MAGIC),"magic"},
            {new Integer(CharStats.STAT_SAVE_GAS),"gas"},
            {new Integer(CharStats.STAT_SAVE_FIRE),"fire"},
            {new Integer(CharStats.STAT_SAVE_ELECTRIC),"elec"},
            {new Integer(CharStats.STAT_SAVE_MIND),"mind"},
            {new Integer(CharStats.STAT_SAVE_JUSTICE),"justice"},
            {new Integer(CharStats.STAT_SAVE_COLD),"cold"},
            {new Integer(CharStats.STAT_SAVE_ACID),"acid"},
            {new Integer(CharStats.STAT_SAVE_WATER),"water"},
            {new Integer(CharStats.STAT_SAVE_UNDEAD),"evil"},
            {new Integer(CharStats.STAT_SAVE_DISEASE),"disease"},
            {new Integer(CharStats.STAT_SAVE_POISON),"poison"},
            {new Integer(CharStats.STAT_SAVE_PARALYSIS),"paralyze"},
            {new Integer(CharStats.STAT_SAVE_TRAPS),"traps"}
    };
    
	public void setMiscText(String newText)
	{
		super.setMiscText(newText);
		adjCharStats=(CharStats)CMClass.getCommon("DefaultCharStats");
        ignoreCharStats=true;
        for(int i=0;i<stats.length;i++)
        {
            adjCharStats.setStat(((Integer)stats[i][0]).intValue(),getProtection((String)stats[i][1]));
            if(adjCharStats.getStat(((Integer)stats[i][0]).intValue())!=0)
                ignoreCharStats=false;
        }
        mask=new Vector();
        parmString=newText;
        int maskindex=newText.toUpperCase().indexOf("MASK=");
        if(maskindex>0)
        {
            maskString=newText.substring(maskindex+5).trim();
            if(maskString.length()>0)
                CMParms.addToVector(CMLib.masking().maskCompile(maskString),mask);
            parmString=newText.substring(0,maskindex).trim();
        }
	}

    protected void ensureStarted()
	{
		if(adjCharStats==null)
			setMiscText(text());
	}

	public void affectCharStats(MOB affectedMOB, CharStats affectedStats)
	{
		ensureStarted();
        if((!ignoreCharStats)
        &&(canResist(affectedMOB))
        &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,affectedMOB))))
            for(int i=0;i<stats.length;i++)
                affectedStats.setStat(((Integer)stats[i][0]).intValue(),affectedStats.getStat(((Integer)stats[i][0]).intValue())+adjCharStats.getStat(((Integer)stats[i][0]).intValue()));
		super.affectCharStats(affectedMOB,affectedStats);
	}


	public boolean checkProtection(String protType)
	{
		int prot=getProtection(protType);
		if(prot==0) return false;
		if(prot<5) prot=5;
		if(prot>95) prot=95;
		if(CMLib.dice().rollPercentage()<prot)
			return true;
		return false;
	}

	public int getProtection(String protType)
	{
        String nonMask=parmString.toUpperCase();
		int z=nonMask.indexOf(protType.toUpperCase());
		if(z<0) 
            return 0;
		int x=nonMask.indexOf("%",z+protType.length());
		if(x<0)
			return 50;
		int mul=1;
		int tot=0;
		while((--x)>=0)
		{
			if(Character.isDigit(nonMask.charAt(x)))
				tot+=CMath.s_int(""+nonMask.charAt(x))*mul;
			else
			{
				if(nonMask.charAt(x)=='-')
					mul=mul*-1;
				x=-1;
			}
			mul=mul*10;
		}
		return tot;
	}
    
	public void resistAffect(CMMsg msg, MOB mob, Ability me, Vector mask)
	{
		if(mob.location()==null) return;
		if(mob.amDead()) return;
		if(!msg.amITarget(mob)) return;

		if((msg.targetMinor()==CMMsg.TYP_DAMAGE)
		&&((msg.value())>0)
		&&(msg.tool()!=null)
	    &&(msg.tool() instanceof Weapon))
		{
			if(checkProtection("weapons"))
            {
                if((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob)))
    				msg.setValue((int)Math.round(CMath.mul(msg.value(),1.0-CMath.div(getProtection("weapons"),100.0))));
            }
			else
			{
				Weapon W=(Weapon)msg.tool();
				if((W.weaponType()==Weapon.TYPE_BASHING)
                &&(checkProtection("blunt"))
                &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob))))
					msg.setValue((int)Math.round(CMath.mul(msg.value(),1.0-CMath.div(getProtection("blunt"),100.0))));
				if((W.weaponType()==Weapon.TYPE_PIERCING)
                &&(checkProtection("pierce"))
                &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob))))
					msg.setValue((int)Math.round(CMath.mul(msg.value(),1.0-CMath.div(getProtection("pierce"),100.0))));
			    if((W.weaponType()==Weapon.TYPE_SLASHING)
                &&(checkProtection("slash"))
                &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob))))
			    	msg.setValue((int)Math.round(CMath.mul(msg.value(),1.0-CMath.div(getProtection("slash"),100.0))));
			}
			return;
		}
	}

    public String accountForYourself()
    { return "The owner gains resistances: "+describeResistance(text());}

	public boolean isOk(CMMsg msg, Ability me, MOB mob, Vector mask)
	{
		if(!CMath.bset(msg.targetCode(),CMMsg.MASK_MALICIOUS))
			return true;

		if(CMath.bset(msg.targetCode(),CMMsg.MASK_MAGIC))
		{
			if(msg.tool() instanceof Ability)
			{
				Ability A=(Ability)msg.tool();
				if(CMath.bset(A.flags(),Ability.FLAG_TRANSPORTING))
				{
					if((checkProtection("teleport"))
                    &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob))))
					{
						msg.source().tell("You can't seem to fixate on '"+mob.name()+"'.");
						return false;
					}
				}
				else
				if(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PRAYER)
				&&(CMath.bset(A.flags(),Ability.FLAG_HOLY))
				&&(!CMath.bset(A.flags(),Ability.FLAG_UNHOLY)))
				{
					if((checkProtection("holy"))
                    &&((mask.size()==0)||(CMLib.masking().maskCheck(mask,mob))))
					{
						mob.location().show(msg.source(),mob,CMMsg.MSG_OK_VISUAL,"Holy energies from <S-NAME> are repelled from <T-NAME>.");
						return false;
					}
				}
			}
		}
		return true;
	}
    
    public String describeResistance(String text)
    {
        String id=parmString+".";
        if(maskString.length()>0)
            id+="  Restrictions: "+CMLib.masking().maskDesc(maskString)+".";
        return id;
    }
    
    public boolean canResist(Environmental E)
    {
        if((affected instanceof Item)
        &&(E instanceof MOB)
        &&(!((Item)affected).amDestroyed())
        &&(E==((Item)affected).owner()))
            return true;
        return false;
    }

	public boolean okMessage(Environmental myHost, CMMsg msg)
	{
        if(canResist(msg.target()))
		{
			MOB mob=(MOB)msg.target();
			if((msg.amITarget(mob))&&(mob.location()!=null))
			{
				if((msg.value()<=0)&&(!isOk(msg,this,mob,mask)))
					return false;
				resistAffect(msg,mob,this,mask);
			}
		}
		return true;
	}
}
