contract DigitalAssetCoin is StandardToken {
    string public constant standard = 'DigitalAssetCoin 1.0';
    string public constant symbol = "DAC";
    string public constant name = "Digital Asset Coin";
    uint8 public constant decimals = 0;

    // Balances for each account
    mapping(address => uint256) transmutedBalances;

    // Triggered whenever approve(address _spender, uint256 _value) is called.
    event NewDigitalAsset(address indexed _creator, address indexed _assetContract);
    event TransmutedTransfer(address indexed _from, address indexed _to, uint256 _value, address _tokenAddress, string _tokenName, string _tokenSymbol);

    //List of Asset Tokens
    uint256 public totalAssetTokens;
    address[] addressList;
    mapping(address => uint256) addressDict;
    
    // Owner of this contract
    address public owner;

    // Functions with this modifier can only be executed by the owner
    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }
    
    // Allow Owner to be changed by exisiting owner (Dev management)
    function changeOwner(address _newOwner) onlyOwner() {
        owner = _newOwner;
    }

    // Constructor
    function DigitalAssetCoin() {
        owner = msg.sender;
        _totalSupply = 100000000000;
        balances[owner] = _totalSupply;
        totalAssetTokens = 0;
        addressDict[this] = totalAssetTokens;
        addressList.length = 1;
        addressList[totalAssetTokens] = this;
    }

    function CreateDigitalAssetToken(
    uint256 coinsAmount,
    uint256 initialSupply,
    string assetTokenName,
    string tokenSymbol,
    string _assetID,
    string _assetMeta
    ) {
        //Not Enought Coins to Create new Asset Token
        require(balanceOf(msg.sender) > coinsAmount);
        
        //Cant be smaller than 1 or larger than 1
        require(coinsAmount == 1);

        //Send coins back to master escrow
        DigitalAssetToken newToken = new DigitalAssetToken(this, msg.sender,initialSupply,assetTokenName,tokenSymbol,_assetID,_assetMeta);
        //Use coins for Token Creation
        transmuteTransfer(msg.sender, 1, newToken, assetTokenName, tokenSymbol);
        insetAssetToken(newToken);
    }

    function vaildBalanceForTokenCreation (address toCheck) external returns (bool success) {
        address sender = msg.sender;
        address org = tx.origin; 
        address tokenMaster = this;

        //Can not be run from human or master contract
        require(sender != org || sender != tokenMaster);

        //Check if message send can make token
        if (balances[toCheck] >= 1) {
            return true;
        } else {
            return false;
        }

    }
    
    function insetAssetToken(address assetToken) internal {
        totalAssetTokens = totalAssetTokens + 1;
        addressDict[assetToken] = totalAssetTokens;
        addressList.length += 1;
        addressList[totalAssetTokens] = assetToken;
        NewDigitalAsset(msg.sender, assetToken);
        //Transfer(msg.sender, assetToken, 777);
    }
    
    function getAssetTokenByIndex (uint256 idx) external returns (address assetToken) {
        require(totalAssetTokens <= idx);
        return addressList[idx];
    }
    
    function doesAssetTokenExist (address assetToken) external returns (bool success) {
        uint256 value = addressDict[assetToken];
        if(value == 0)
            return false;
        else
            return true;
    }
    
    // Transmute DAC to DAT
    function transmuteTransfer(address _from, uint256 _value, address tokenAddress, string tokenName, string tokenSymbol) returns (bool success) {
        if (balances[_from] >= _value && _value > 0) {
            balances[_from] -= _value;
            transmutedBalances[this] += _value;
            TransmutedTransfer(_from, this, _value, tokenAddress, tokenName, tokenSymbol);
            return true;
        } else {
            return false;
        }
    }

}
function changeOwner(address _newOwner) onlyOwner() {
    owner = _newOwner;
}

// Allow Owner to be changed by exisiting owner (Dev management)