contract GXC is ERC20, SafeMath, Ownable {
    // Public variables of the token
    string public name;
    string public symbol;
    uint8 public decimals; // How many decimals to show.
    string public version = 'v0.1';
    uint public initialSupply;
    uint public totalSupply;
    bool public locked;
    address public crowdSaleAddress;
    uint multiplier = 10000000000;        
    
    uint256 public totalMigrated;

    mapping(address => uint) balances;
    mapping(address => mapping(address => uint)) allowed;
    

    // Lock transfer during the ICO
    modifier onlyUnlocked() {
        if (msg.sender != crowdSaleAddress && locked && msg.sender != owner) revert();
        _;
    }

    modifier onlyAuthorized() {
        if ( msg.sender != crowdSaleAddress && msg.sender != owner) revert();
        _;
    }

    // The GXC Token constructor
    function GXC(address _crowdSaleAddress) {        
        locked = true;  // Lock the transfer of tokens during the crowdsale
        initialSupply = 10000000 * multiplier;
        totalSupply = initialSupply;
        name = 'GXC'; // Set the name for display purposes
        symbol = 'GXC'; // Set the symbol for display purposes
        decimals = 10; // Amount of decimals for display purposes
        crowdSaleAddress = _crowdSaleAddress;               
        balances[crowdSaleAddress] = totalSupply;       
    }


    function restCrowdSaleAddress(address _newCrowdSaleAddress) onlyAuthorized() {
            crowdSaleAddress = _newCrowdSaleAddress;
    }

    

    function unlock() onlyAuthorized {
        locked = false;
    }

      function lock() onlyAuthorized {
        locked = true;
    }

    function burn( address _member, uint256 _value) onlyAuthorized returns(bool) {
        balances[_member] = safeSub(balances[_member], _value);
        totalSupply = safeSub(totalSupply, _value);
        Transfer(_member, 0x0, _value);
        return true;
    }

    function transfer(address _to, uint _value) onlyUnlocked returns(bool) {
        balances[msg.sender] = safeSub(balances[msg.sender], _value);
        balances[_to] = safeAdd(balances[_to], _value);
        Transfer(msg.sender, _to, _value);
        return true;
    }

    /* A contract attempts to get the coins */
    function transferFrom(address _from, address _to, uint256 _value) onlyUnlocked returns(bool success) {
        if (balances[_from] < _value) revert(); // Check if the sender has enough
        if (_value > allowed[_from][msg.sender]) revert(); // Check allowance
        balances[_from] = safeSub(balances[_from], _value); // Subtract from the sender
        balances[_to] = safeAdd(balances[_to], _value); // Add the same to the recipient
        allowed[_from][msg.sender] = safeSub(allowed[_from][msg.sender], _value);
        Transfer(_from, _to, _value);
        return true;
    }

    function balanceOf(address _owner) constant returns(uint balance) {
        return balances[_owner];
    }

    function approve(address _spender, uint _value) returns(bool) {
        allowed[msg.sender][_spender] = _value;
        Approval(msg.sender, _spender, _value);
        return true;
    }


    function allowance(address _owner, address _spender) constant returns(uint remaining) {
        return allowed[_owner][_spender];
    }
}
// The GXC token
function transferFrom(address _from, address _to, uint256 _value) onlyUnlocked returns(bool success) {
    if (balances[_from] < _value) revert(); // Check if the sender has enough
    if (_value > allowed[_from][msg.sender]) revert(); // Check allowance
    balances[_from] = safeSub(balances[_from], _value); // Subtract from the sender
    balances[_to] = safeAdd(balances[_to], _value); // Add the same to the recipient
    allowed[_from][msg.sender] = safeSub(allowed[_from][msg.sender], _value);
    Transfer(_from, _to, _value);
    return true;
}

/* A contract attempts to get the coins */