/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package dataStructures;

import java.util.HashMap;
import java.util.Collection;

import symbols.value.StaticVal;
import symbols.value.Value;
import symbols.value.Value_t;
import symbols.value.DynamicVal;

import static utils.Constants.NULL;
import static utils.Constants.UNDEFINED;

public class FoxArray extends AFoxDataStructure {

    private final HashMap<Value, Value> _numberIndexedData;
    private final HashMap<Value, Value> _otherTypeIndexedData;

    private int _numberIndexedDataMaxIndex;

    public FoxArray() {
        _numberIndexedData = new HashMap<>();
        _otherTypeIndexedData = new HashMap<>();

        _numberIndexedDataMaxIndex = 0;
    }

    public FoxArray(HashMap<Value, Value> numberIndexedData) {
        _numberIndexedData = numberIndexedData;
        _otherTypeIndexedData = new HashMap<>();

        _numberIndexedDataMaxIndex = numberIndexedData.size();
    }

    public FoxArray(FoxArray foxArray) {
        this();

        for (int i = 0; i < foxArray.size(); i++) {
            StaticVal key = new StaticVal(Value_t.INTEGER, i);
            Value value = foxArray.get(key);

            if (value != NULL) {
                this.put(key, value);
            }
        }

        foxArray.getOtherTypeIndexedData().entrySet().stream().forEach((pair) -> {
            Value key = new StaticVal(pair.getKey());
            Value value = new DynamicVal((DynamicVal) pair.getValue());

            this.put(key, value);
        });

    }

    @Override
    public final void put(Value key, Value value) {

        if (key.isInteger() || key.isConvertedToInteger()) {
            _numberIndexedData.put(key, value);

            int newIndex = key.isInteger() ? (int) key.getData() : Integer.parseInt((String) key.getData());

            if (_numberIndexedDataMaxIndex == newIndex) {
                _numberIndexedDataMaxIndex++;
            } else {
                _numberIndexedDataMaxIndex = newIndex + 1;
            }

        } else {
            _otherTypeIndexedData.put(key, value);
        }
    }

    public Value get(int value) {
        return get(new StaticVal(Value_t.INTEGER, value));
    }

    @Override
    public Value get(Value key) {
        Value value = _numberIndexedData.get(key);
        if (value != null) {
            return value;
        }

        value = _otherTypeIndexedData.get(key);
        if (value != null) {
            return value;
        }

        return NULL;
    }

    public void add(Value value) {
        Value key = new StaticVal(Value_t.INTEGER, _numberIndexedDataMaxIndex);
        _numberIndexedDataMaxIndex++;

        _numberIndexedData.put(key, value);
    }

    @Override
    public void remove(Value key) {
        if (_numberIndexedData.containsKey(key)) {

            if ((int) key.getData() == (_numberIndexedDataMaxIndex - 1)) {
                _numberIndexedData.remove(key);
                _numberIndexedDataMaxIndex--;

            } else {
                _numberIndexedData.put(key, UNDEFINED);
            }

        } else {
            _otherTypeIndexedData.remove(key);
        }
    }

    @Override
    public int size() {
        return _numberIndexedDataMaxIndex;
    }

    public HashMap<Value, Value> getNumberIndexedData() {
        return _numberIndexedData;
    }

    public HashMap<Value, Value> getOtherTypeIndexedData() {
        return _otherTypeIndexedData;
    }

    @Override
    public HashMap<Value, Value> values() {
        Collection<Value> valuesCollection = _numberIndexedData.values();
        HashMap<Value, Value> values = new HashMap<>();
        int count = 0;

        for (Value value : valuesCollection) {
            StaticVal key = new StaticVal(Value_t.INTEGER, count);
            StaticVal val = new StaticVal(value);
            values.put(key, val);
            count++;
        }

        return values;
    }

    @Override
    public String toString() {
        StringBuilder msg = new StringBuilder();

        msg.append("[ ");
        for (int i = 0; i < _numberIndexedDataMaxIndex; i++) {
            StaticVal key = new StaticVal(Value_t.INTEGER, i);
            Value data = _numberIndexedData.get(key);
            if (data != null) {
                msg.append(_numberIndexedData.get(key).getData()).append(", ");
            } else {
                msg.append(", ");
            }
        }

        msg.setCharAt(msg.length() - 1, ']');
        if (msg.length() > 2) {
            msg.setCharAt(msg.length() - 2, ' ');
        }

        return msg.toString();
    }

}

@@ -1720,25 +1720,24 @@
 ue value) %7B%0A
-%0A
         if (
@@ -1756,37 +1756,35 @@
 r() 
-%7C%7C key.isConvertedToInteger()
+&& (int) key.getData() %3E= 0
 ) %7B%0A
@@ -1863,87 +1863,26 @@
 x = 
-key.isInteger() ? (int) key.getData() : Integer.parseInt((String) key.getData()
+(int) key.getData(
 );%0A%0A

Add to indexed part of FoxArray only integer type keys and greater equal zero and the other to otherindexed keys.