/*
 * 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 br.com.ctecinf.swing;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.swing.AbstractListModel;

/**
 *
 * @author Cássio Conceição
 * @param <T>
 * @since 24/09/2019
 * @version 1909
 * @see http://ctecinf.com.br/
 */
public class ListModel<T> extends AbstractListModel<T> implements Serializable {

    protected List<T> data;

    public ListModel() {
        this.data = Collections.synchronizedList(new ArrayList());
    }

    public ListModel(T[] data) {
        this.data = Collections.synchronizedList(new ArrayList(Arrays.asList(data)));
    }

    public ListModel(List<T> data) {
        this.data = Collections.synchronizedList(new ArrayList(data));
    }

    public List<T> getData() {

        if (this.data == null) {
            this.data = Collections.synchronizedList(new ArrayList());
        }

        return this.data;
    }

    public void setData(List<T> data) {
        this.data = data == null ? Collections.synchronizedList(new ArrayList()) : Collections.synchronizedList(new ArrayList(data));
        fireContentsChanged(this, 0, getSize());
    }

    public void add(T row) {
        if (getData().indexOf(row) == -1) {
            getData().add(row);
            fireIntervalAdded(this, getData().size() - 1, getData().size() - 1);
        }
    }

    public void update(int index, T row) {
        if (!getData().isEmpty() && index >= 0 && index < getData().size()) {
            getData().set(index, row);
            fireContentsChanged(this, index, index);
        }
    }

    public void remove(T obj) {

        int index = getData().indexOf(obj);

        if (index > -1) {
            getData().remove(obj);
            fireIntervalRemoved(this, index, index);
        }
    }

    public void remove(int index) {
        if (!getData().isEmpty() && index >= 0 && index < getData().size() && getData().remove(getData().remove(index))) {
            fireIntervalRemoved(this, index, index);
        }
    }

    public void removeAll() {
        if (!getData().isEmpty()) {
            int size = getData().size() - 1;
            getData().clear();
            fireIntervalRemoved(this, 0, size);
        }
    }

    @Override
    public int getSize() {
        return this.data == null ? 0 : this.data.size();
    }

    @Override
    public T getElementAt(int index) {

        if (index > -1 && index < getSize()) {
            return this.data.get(index);
        }

        return null;
    }

}
