/
codebase/src/net/sourceforge/pain/admin/console/command/
codebase/src/net/sourceforge/pain/data/role/
codebase/src/net/sourceforge/pain/network/console/telnet/
codebase/src/net/sourceforge/pain/network/guitool/
codebase/src/net/sourceforge/pain/plugin/
codebase/src/net/sourceforge/pain/util/
db/src/net/sourceforge/pain/util/
gui/
gui/lib/
gui/src/net/sourceforge/pain/tools/guitool/dbbrowse/
gui/src/net/sourceforge/pain/tools/guitool/dialog/
gui/src/net/sourceforge/pain/tools/guitool/menu/
gui/src/net/sourceforge/pain/tools/guitool/resources/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/
gui/src/net/sourceforge/pain/tools/guitool/resources/images/explorer/
mudlibs/tinylib/
mudlibs/tinylib/area/
mudlibs/tinylib/etc/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/prototype/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/data/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/affect/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/deploy/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/event/guitool/event/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/fn/util/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/logic/trigger/impl/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/command/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/reset/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/shutdown/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/plugin/social/
mudlibs/tinylib/src/net/sourceforge/pain/tinylib/util/
tests/
tests/src/
tests/src/net/sourceforge/pain/db/data/
package net.sourceforge.pain.data;

import net.sourceforge.pain.db.*;
import net.sourceforge.pain.logic.*;
import net.sourceforge.pain.*;

/**
 * Affects persistent image base class
 * Note: Only one affect could be applied to the specified
 * object role(in opposite to object triggers)
 * Affected role could be null.
 * <p/>
 * All subclasses of AffectData and TimedAffectData
 * are DbObjects and should add only new fields to save
 * All subclasses should be defined in data.affects package
 * and should not contain any logical code.
 */
public class AffectData extends DbObject {
    /**
     * affected role, allowed to be null
     */
    private static int AFFECTED_ROLE = 0;
    /**
     * affect type id, object is allowed to be affected with only one affect of specified id
     */
    private static int AFFECT_TYPE = 1;

    /**
     * class that responsible for affect ON/OFF logic (could be null)
     */
    private static int AFFECT_LOGIC_CLASS_NAME = 2;

    /**
     * used by subclasses
     */
    protected static int LAST_BASE_FIELD_INDEX = 2;

    private static int NFIELDS = LAST_BASE_FIELD_INDEX + 1;


    public AffectData() {
    }

    /**
     * @param db
     * @param role            - affected role
     * @param affectImplClass
     * @throws Exception
     */
    public AffectData(PainDB db, Role role, Class affectImplClass, int affectTypeId) throws Exception {
        super(db);
        if (role == null) {
            throw new NullPointerException("affected role is null!");
        }
        if (!Affect.class.isAssignableFrom(affectImplClass)) {
            throw new IllegalArgumentException("Illegal affect  impl class!");
        }
        setAffectClassName(affectImplClass.getName().substring(Codebase.AFFECTS_LOGIC_PACKAGE_PREFIX.length()));
        setAffectedRole(role);
        setAffectType(affectTypeId);
        role.getRoot().addAffect(role, this);
    }

    protected DbClassSchema provideSchema() {
        byte types[] = new byte[NFIELDS];
        String names[] = new String[NFIELDS];
        fillSuperSchema(types, names);
        return new DbClassSchema(types, names);
    }

    protected void fillSuperSchema(byte[] types, String[] names) {
        types[AFFECTED_ROLE] = DbType.REFERENCE;
        names[AFFECTED_ROLE] = "affected_role";

        types[AFFECT_TYPE] = DbType.INT;
        names[AFFECT_TYPE] = "affect_type";


        types[AFFECT_LOGIC_CLASS_NAME] = DbType.STRING;
        names[AFFECT_LOGIC_CLASS_NAME] = "timed_affect_class_name";
    }

    final void setAffectType(int affectType) {
        setInt(AFFECT_TYPE, affectType);
    }

    public final int getAffectType() {
        return getInt(AFFECT_TYPE);
    }

    /**
     * affected role is allowed to be null
     */
    void setAffectedRole(Role role) {
        setReference(AFFECTED_ROLE, role);
    }

    /**
     * affected role is allowed to be null
     */
    public Role getAffectedRole() {
        return (Role) getReference(AFFECTED_ROLE);
    }


    /**
     * suffix of affect class name in "...logic.affect." package
     */
    public String getAffectClassName() {
        return getString(AFFECT_LOGIC_CLASS_NAME);
    }

    void setAffectClassName(String className) {
        setString(AFFECT_LOGIC_CLASS_NAME, className);
    }

    public int getAffectOffTime() {
        return -1;
    }
}