// Path: src/main/java/com/amanvishnani/sim8085/domain/Flag.java
// public enum Flag {
//     S, Z, Ac, P, Cy;
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IData.java
// public interface IData {
//     IData ZERO = Data.from("00");
//     String hexValue();
//     Integer intValue();
//     IOperationResult add(IData data);
//     IOperationResult add(IData data, Integer carry);
//     IOperationResult minus(IData data);
//     IRegister toRegister();
//     public IData getLSB();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IOperationResult.java
// public interface IOperationResult {
//     IData getData();
//     IFlags getFlags();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IRegister.java
// public interface IRegister extends IData {
//     void update(IData data);
// }


import com.amanvishnani.sim8085.domain.Flag;
import com.amanvishnani.sim8085.domain.IData;
import com.amanvishnani.sim8085.domain.IOperationResult;
import com.amanvishnani.sim8085.domain.IRegister;
import java.util.Objects;
    public IOperationResult add(IData data) {
        return this.add(data, 0);
    }

    // @TODO: Unit test this
    @Override
    public IData getLSB() {
        String s = this.getDataValue();
        return Data.from(s.substring(s.length() - 2));
    }

    @Override
    public IOperationResult add(IData data, Integer carry) {
        Flags flags = Flags.newInstance();
        int r1, r2, r3;
        r1 = this.intValue();
        r2 = data.intValue();
        r3 = r1 + r2 + carry;
        if (r3 > 255) {
            flags.setFlag(Flag.Cy, 1);
        }
        if (this.getLSB().intValue() + data.getLSB().intValue() + carry > 15) {
            flags.setFlag(Flag.Ac, 1);
        }
        Data temp = Data.from(r1 + r2 + carry);
        flags.setFlag(Flag.P, temp.getParity());
        return OperationResult.from(temp, flags);
    }

    @Override
// Path: src/main/java/com/amanvishnani/sim8085/domain/Flag.java
// public enum Flag {
//     S, Z, Ac, P, Cy;
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IData.java
// public interface IData {
//     IData ZERO = Data.from("00");
//     String hexValue();
//     Integer intValue();
//     IOperationResult add(IData data);
//     IOperationResult add(IData data, Integer carry);
//     IOperationResult minus(IData data);
//     IRegister toRegister();
//     public IData getLSB();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IOperationResult.java
// public interface IOperationResult {
//     IData getData();
//     IFlags getFlags();
// }
// 
// Path: src/main/java/com/amanvishnani/sim8085/domain/IRegister.java
// public interface IRegister extends IData {
//     void update(IData data);
// }


// Path: src/main/java/com/amanvishnani/sim8085/domain/Impl/Data.java
import com.amanvishnani.sim8085.domain.Flag;
import com.amanvishnani.sim8085.domain.IData;
import com.amanvishnani.sim8085.domain.IOperationResult;
import com.amanvishnani.sim8085.domain.IRegister;
import java.util.Objects;

    public IOperationResult add(IData data) {
        return this.add(data, 0);
    }

    // @TODO: Unit test this
    @Override
    public IData getLSB() {
        String s = this.getDataValue();
        return Data.from(s.substring(s.length() - 2));
    }

    @Override
    public IOperationResult add(IData data, Integer carry) {
        Flags flags = Flags.newInstance();
        int r1, r2, r3;
        r1 = this.intValue();
        r2 = data.intValue();
        r3 = r1 + r2 + carry;
        if (r3 > 255) {
            flags.setFlag(Flag.Cy, 1);
        }
        if (this.getLSB().intValue() + data.getLSB().intValue() + carry > 15) {
            flags.setFlag(Flag.Ac, 1);
        }
        Data temp = Data.from(r1 + r2 + carry);
        flags.setFlag(Flag.P, temp.getParity());
        return OperationResult.from(temp, flags);
    }

    @Override
    public IOperationResult minus(IData data) {