/**
 * 天赋类别对象。
 * @create   2004-9-29 source0
 * @author   source0 source0@hotmail.com
 * @copyright 版权所有（C） 2004  source0
 *                这一程序是自由软件，你可以遵照自由软件基金会出版的GNU通用
 *            公共许可证条款来修改和重新发布这一程序。或者用许可证的第二版，
 *            或者（根据你的选择）用任何更新的版本。
 *                发布这一程序的目的是希望它有用，但没有任何担保。甚至没有
 *            适合特定目的的隐含的担保。更详细的情况请参阅GNU通用公共许可证。
 *                你应该已经和程序一起收到一份GNU通用公共许可证的副本。如果
 *            还没有，写信给：
 *                The Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 *                MA02139, USA
 */

/**
 * 天赋类别对象。
 * @param id 此类别的ID。
 * @param name 此类别的名字。
 * @param imgPath 图片的基准目录。
 * @param image 背景图片。
 */
function CTalentClass(id, name, pth, img){
    this.id = id;
    this.name = name;
    this.path = ".";
    this.image = "";

    if ( pth ){
        this.path = pth;
    }
    if ( img ){
        this.image = img;
    }

    var talentViews = new Array();//保存所有天赋视图实例的 CTalentView 数组（Map）。
    var amount = 0;//已经在本天赋类别上增加的点数。

    /**
     * 添加一个天赋。
     * @param id 天赋ID。
     * @param talent 天赋模型实例。
     * @param icon 图标。
     * @param position 该天赋在显示时所在的列（所在行由天赋的层次决定）。
     */
    this.add = function(talent, icon, position){
        var tv = new CTalentView(this, talent, icon, position);
        talentViews[talent.id] = tv;
        return tv;
    }
    /**
     * 删除一个天赋。
     * @param id 天赋ID。
     * @return 被删除的天赋视图实例。
     * @create 2004-10-06 source0
     */
    this.remove = function(id){
        if (( null == id ) || ( null == talentViews[id])){
            return;
        }
        var oldTalentViews = talentViews;
        talentViews = new Array();
        for ( var key in oldTalentViews ){
            if ( key != id ){
                talentViews[key] = oldTalentViews[key];
            }
        }
        return oldTalentViews[id];
    }
    /**
     * 得到指定的天赋视图实例。
     * @param id 天赋ID。
     * @return 天赋视图的实例，如果不存在，返回 null 。
     */
    this.getTalentView = function(id){
        return talentViews[id];
    }
    /**
     * 得到所有天赋视图数组。
     * @return 天赋视图数组。
     */
    this.getTalentViews = function(){
        return talentViews;
    }
    /**
     * 根据模型实例，得到指定的天赋视图实例。
     * @param model 模型实例。
     */
    this.getTalentViewByModel = function(model){
        for ( var key in talentViews ){
            if ( talentViews[key].model == model ){
                return talentViews[key];
            }
        }
        return null;
    }
    /**
     * 查找引用指定天赋作为前提条件的所有天赋的ID。
     * @param id 被引用的天赋的ID。
     * @return 如果该天赋被其它天赋作为前提条件引用，返回引用该天赋的天赋ID数组。否则返回空数组。
     * @create 2004-10-21 source0
     */
    this.getReferenceTalents = function (id){
        var rt = new Array();
        if ( null == id ){
            return rt;
        }
        var tvs = this.getTalentViews();
        for ( var key in tvs ){
            var reqs = tvs[key].model.requirements;
            if (( null == reqs ) || ( 0 >= reqs.length )){
                continue;
            }
            for ( var i = 0; i < reqs.length; i++ ){
                if ( reqs[i].talent == id ){
                    rt[rt.length] = tvs[key].model.id;
                }
            }
        }
        return rt;
    }


    /**
     * 升级指定的天赋。
     * @param id 天赋的ID。
     */
    this.update = function(id){
        this.getTalentView(id).update();
    }
    /**
     * 撤销对指定天赋的升级。
     * @param id 天赋的ID。
     */
    this.undoUpdate = function(id){
        var tv = this.getTalentView(id);
        /* 如果当前天赋未曾升级，什么也不做。 */
        if ( tv.getRank() <= 0 ){
            return;
        }
        if ( this.canUndoUpdate(id) ){
            tv.undoUpdate();
            amount--;
        }
    }
    /**
     * 检查指定的天赋能否被撤销升级。
     * @param id 天赋的ID。
     * @return 如果该天赋不存在，返回 false ，如果未曾升级，返回 false 。
     *          如果引用该天赋的任何一个天赋不允许撤销，返回 false。
     *          如果存在超过该天赋层次的天赋，而撤销会导致需要的点数不够，返回 false。
     */
    this.canUndoUpdate = function (id){
        var tv = this.getTalentView(id);
        if ( null == tv ){
            return false;
        }
        if ( tv.getRank() <= 0 ){
            return false;
        }
        /*
        检查对本天赋的引用。如果有引用并且已经被升级，且学习需要的点数大于本天赋的级别，则不能执行撤销。
        */
        var refs = this.getReferenceTalents(id);
        for ( var i = 0; i < refs.length; i++ ){
            var refTV = this.getTalentView(refs[i]);
            if ( refTV.getRank() > 0 )
            {//有引用并且已经被升级
                for ( var r = 0; r < refTV.model.requirements.length; r++ ){
                    if (( refTV.model.requirements[r].talent == id )
                        && ( refTV.model.requirements[r].rank >= tv.getRank() ))
                    {//引用了本天赋，并且学习需要的点数大于本天赋的级别
                        return false;
                    }
                }
            }
        }

        /* 检查撤销后会否导致某些已经学习的技能的前提条件不满足。 */
        var points = 0;
        for ( var key in talentViews )
        {
            if ( talentViews[key].model.tier <= tv.model.tier ){
                points += talentViews[key].getRank();
            }
        }

        for ( var key in talentViews )
        {
            if ((talentViews[key].getRank() > 0)
                && (5 * talentViews[key].model.tier >= points ))
            {
                return false;
            }
        }
        return true;
    }
    /**
     * 重置。
     * @return 返回回收的天赋点数。
     */
    this.reset = function(){
        var rt = amount;
        amount = 0;
        for ( var key in talentViews ){
            talentViews[key].reset();

            /** 如果某个天赋的ID发生了变化，要更新所有的引用信息。 */
            if ( key != talentViews[key].model.id ){
                var tv = this.remove(key);
                talentViews[tv.model.id] = tv;

                /** 查找引用指定天赋作为前提条件的所有天赋，修改引用ID。 */
                var reqs;
                for ( var refId in talentViews ){
                    reqs = talentViews[refId].model.requirements;
                    if (( null == reqs ) || ( 0 >= reqs.length )){
                        continue;
                    }
                    for ( var i = 0; i < reqs.length; i++ ){
                        if ( reqs[i].talent == key ){
                            reqs[i].talent = tv.model.id;
                        }
                    }
                }

            }
        }
        return rt;
    }
    /**
     * 已经在本天赋类别上增加的点数。
     * @return 已经在本天赋类别上增加的点数。
     */
    this.getAmount = function(){
        return amount;
    }

    /**
     * 响应天赋已升级操作。
     * @param view 天赋视图。
     * @param rank 升的级别。默认为 1 。
     */
    this.talentUpdated = function(view, rank){
        if ( rank ){
            amount += parseInt(rank);
        } else {
            amount++;
        }
    }
    this.toString = function(){
        var result = new String();
        var count = 0;
        for ( var key in talentViews ){
            result += "<BR/>\n" + talentViews[key];
            count++;
        }
        return "CTalentClass["
            + "名称=" + this.name + ", "
            + "天赋总数=" + count
            + result
            + "]";
    }
}