contract LockToken is BaseToken {
    struct LockMeta {
        uint256 amount;
        uint256 endtime;
        bool    deleted;
    }

    // 0 删除 1 静态 2 动态
    event Locked(uint32 indexed _type, address indexed _who, uint256 _amounts, uint256 _endtimes);
    event Released(uint32 indexed _type, address indexed _who, uint256 _amounts);
    //  0 静态 1 动态 2 总的
    mapping (address => mapping(uint32 => uint256)) public lockedAmount;
     // 0 静态 1 动态
    mapping (address => mapping(uint32 => LockMeta[])) public lockedDetail;

    function _transfer(address _from, address _to, uint _value) internal {
        require(balanceOf[_from] >= _value + lockedAmount[_from][2]);
        super._transfer(_from, _to, _value);
    }

    function lockRelease() public whenNotStoped {
        
        require(lockedAmount[msg.sender][3] != 0);

        uint256 fronzed_released = 0;
        uint256 dynamic_released = 0;

        if ( lockedAmount[msg.sender][0] != 0 )
        {
            for (uint256 i = 0; i < lockedDetail[msg.sender][0].length; i++) {

                LockMeta storage _meta = lockedDetail[msg.sender][0][i];
                if ( !_meta.deleted && _meta.endtime <= now)
                {
                    _meta.deleted = true;
                    fronzed_released = fronzed_released.add(_meta.amount);
                    emit Released(1, msg.sender, _meta.amount);
                }
            }
        }

        if ( lockedAmount[msg.sender][1] != 0 )
        {
            for (uint256 i = 0; i < lockedDetail[msg.sender][1].length; i++) {

                LockMeta storage _meta = lockedDetail[msg.sender][0][i];
                if ( !_meta.deleted && _meta.endtime <= now)
                {
                    _meta.deleted = true;
                    dynamic_released = dynamic_released.add(_meta.amount);
                    emit Released(2, msg.sender, _meta.amount);
                    
                }
            }
        }

        if ( fronzed_released > 0 || dynamic_released > 0 ) {
            lockedAmount[msg.sender][0] = lockedAmount[msg.sender][0].sub(fronzed_released);
            lockedAmount[msg.sender][1] = lockedAmount[msg.sender][1].sub(dynamic_released);
            lockedAmount[msg.sender][2] = lockedAmount[msg.sender][2].sub(dynamic_released).sub(fronzed_released);
        }
    }

    // type = 0 删除 1 静态  2 动态
    function lock(uint32 _type, address _who, uint256[] memory _amounts, uint256[] memory _endtimes) public  onlyOwnerOrCmo {
        require(_amounts.length == _endtimes.length);

        uint256 _total;

        if ( _type == 2 ) {
            if ( lockedDetail[_who][1].length > 0 )
            {
                emit Locked(0, _who, lockedAmount[_who][1], 0);
                delete lockedDetail[_who][1];
            }

            for (uint256 i = 0; i < _amounts.length; i++) {
                _total = _total.add(_amounts[i]);
                lockedDetail[_who][1].push(LockMeta({
                    amount: _amounts[i],
                    endtime: _endtimes[i],
                    deleted:false
                }));
                emit Locked(2, _who, _amounts[i], _endtimes[i]);
            }
            lockedAmount[_who][1] = _total;
            lockedAmount[_who][2] = lockedAmount[_who][0].add(_total);
            return;
        }


        if ( _type == 1 ) {
            if ( lockedDetail[_who][0].length > 0 )
            {
                revert();
            }

            for (uint256 i = 0; i < _amounts.length; i++) {
                _total = _total.add(_amounts[i]);
                lockedDetail[_who][0].push(LockMeta({
                    amount: _amounts[i],
                    endtime: _endtimes[i],
                    deleted:false
                }));
                emit Locked(1, _who, _amounts[i], _endtimes[i]);
            }
            lockedAmount[_who][0] = _total;
            lockedAmount[_who][2] = lockedAmount[_who][1].add(_total);
            return;
        }

        if ( _type == 0 ) {
            lockedAmount[_who][2] = lockedAmount[_who][2].sub(lockedAmount[_who][1]);
            emit Locked(0, _who, lockedAmount[_who][1], 0);
            delete lockedDetail[_who][1];
            
        }
    }
}
function lock(uint32 _type, address _who, uint256[] memory _amounts, uint256[] memory _endtimes) public  onlyOwnerOrCmo {
    require(_amounts.length == _endtimes.length);

    uint256 _total;

    if ( _type == 2 ) {
        if ( lockedDetail[_who][1].length > 0 )
        {
            emit Locked(0, _who, lockedAmount[_who][1], 0);
            delete lockedDetail[_who][1];
        }

        for (uint256 i = 0; i < _amounts.length; i++) {
            _total = _total.add(_amounts[i]);
            lockedDetail[_who][1].push(LockMeta({
                amount: _amounts[i],
                endtime: _endtimes[i],
                deleted:false
            }));
            emit Locked(2, _who, _amounts[i], _endtimes[i]);
        }
        lockedAmount[_who][1] = _total;
        lockedAmount[_who][2] = lockedAmount[_who][0].add(_total);
        return;
    }


    if ( _type == 1 ) {
        if ( lockedDetail[_who][0].length > 0 )
        {
            revert();
        }

        for (uint256 i = 0; i < _amounts.length; i++) {
            _total = _total.add(_amounts[i]);
            lockedDetail[_who][0].push(LockMeta({
                amount: _amounts[i],
                endtime: _endtimes[i],
                deleted:false
            }));
            emit Locked(1, _who, _amounts[i], _endtimes[i]);
        }
        lockedAmount[_who][0] = _total;
        lockedAmount[_who][2] = lockedAmount[_who][1].add(_total);
        return;
    }

    if ( _type == 0 ) {
        lockedAmount[_who][2] = lockedAmount[_who][2].sub(lockedAmount[_who][1]);
        emit Locked(0, _who, lockedAmount[_who][1], 0);
        delete lockedDetail[_who][1];
            
    }
}

// type = 0 删除 1 静态  2 动态