/*
 * Copyright (C) 2010 Teleal GmbH, Switzerland
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.teleal.cling.support.avtransport;

import org.teleal.cling.model.types.UnsignedIntegerFourBytes;
import org.teleal.cling.support.avtransport.dto.AVTransportState;
import org.teleal.cling.support.avtransport.event.Event;
import org.teleal.cling.support.avtransport.event.Instance;
import org.teleal.cling.support.avtransport.event.TransportState;
import org.teleal.cling.support.lastchange.LastChange;

import java.util.Iterator;

/**
 *
 */
public class AVTransportLastChange extends LastChange<Event> {

    public AVTransportLastChange() {
        super(new Event(), org.teleal.cling.support.avtransport.event.ObjectFactory.class);
    }

    public AVTransportLastChange(String serialized) {
        super(new Event(), org.teleal.cling.support.avtransport.event.ObjectFactory.class, serialized);
    }

    @Override
    protected void clear(Event event) {
        event.getInstances().clear();
    }

    @Override
    protected void setStateVariable(Event event, UnsignedIntegerFourBytes instanceID, Object o) {
        Instance instance = null;
        for (Instance i : event.getInstances()) {
            if (i.getVal() == instanceID.getValue()) {
                instance = i;
            }
        }
        if (instance == null) {
            instance = new Instance();
            instance.setVal(instanceID.getValue());
            event.getInstances().add(instance);
        }

        Iterator it = instance.getStateVariables().iterator();
        while (it.hasNext()) {
            Object sv = it.next();
            if (sv.getClass().equals(o.getClass())) {
                it.remove();
            }
        }
        instance.getStateVariables().add(o);
    }


    @Override
    protected boolean isEmptyString(Event event) {
        return event == null || event.getInstances().size() == 0;
    }

    @Override
    protected <V> V getStateVariable(Event event, UnsignedIntegerFourBytes instanceId, Class<V> stateVariableType) {
        for (Instance instance : event.getInstances()) {
            if (instance.getVal() == instanceId.getValue()) {
                for (Object o : instance.getStateVariables()) {
                    if (stateVariableType.isAssignableFrom(o.getClass()))
                        return (V) o;
                }
            }
        }
        return null;
    }

    @Override
    protected UnsignedIntegerFourBytes[] getInstanceIds(Event event) {
        UnsignedIntegerFourBytes[] ids = new UnsignedIntegerFourBytes[event.getInstances().size()];
        int i = 0;
        for (Instance instance : event.getInstances()) {
            ids[i++] = new UnsignedIntegerFourBytes(instance.getVal());
        }
        return ids;
    }

    public AVTransportState getTransportState(UnsignedIntegerFourBytes instanceId) {
        return getTransportState(instanceId.getValue());
    }

    public AVTransportState getTransportState(long instanceId) {
        TransportState transportStateVariable = getStateVariable(new UnsignedIntegerFourBytes(instanceId), TransportState.class);
        if (transportStateVariable != null) {
            try {
                return AVTransportState.valueOf(transportStateVariable.getVal());
            } catch (IllegalArgumentException ex) {
                // Ignore
            }
        }
        return null;
    }

}