package psidev.psi.mi.jami.json.elements;

import org.json.simple.JSONValue;
import psidev.psi.mi.jami.json.MIJsonUtils;
import psidev.psi.mi.jami.json.IncrementalIdGenerator;
import psidev.psi.mi.jami.model.*;
import psidev.psi.mi.jami.utils.RangeUtils;

import java.io.IOException;
import java.io.Writer;
import java.util.Map;

/**
 * Json writer for ranges
 *
 * @author Marine Dumousseau (marine@ebi.ac.uk)
 * @version $Id$
 * @since <pre>18/07/14</pre>
 */
public class SimpleJsonRangeWriter implements JsonRangeWriter{

    private Writer writer;
    private Map<String, String> processedInteractors;
    private Map<Entity, Integer> processedParticipants;
    private IncrementalIdGenerator idGenerator;

    /**
     * <p>Constructor for SimpleJsonRangeWriter.</p>
     *
     * @param writer a {@link java.io.Writer} object.
     * @param processedInteractors a {@link java.util.Map} object.
     * @param processedParticipants a {@link java.util.Map} object.
     */
    public SimpleJsonRangeWriter(Writer writer, Map<String, String> processedInteractors,
                                 Map<Entity, Integer> processedParticipants){
        if (writer == null){
            throw new IllegalArgumentException("The json range writer needs a non null Writer");
        }
        this.writer = writer;
        if (processedInteractors == null){
            throw new IllegalArgumentException("The json range writer needs a non null map of processed interactors");
        }
        this.processedInteractors = processedInteractors;
        if (processedParticipants == null){
            throw new IllegalArgumentException("The json range writer needs a non null map of processed participants");
        }
        this.processedParticipants = processedParticipants;
    }

    /**
     * <p>Constructor for SimpleJsonRangeWriter.</p>
     *
     * @param writer a {@link java.io.Writer} object.
     * @param processedInteractors a {@link java.util.Map} object.
     * @param processedParticipants a {@link java.util.Map} object.
     * @param idGenerator a {@link psidev.psi.mi.jami.json.IncrementalIdGenerator} object.
     */
    public SimpleJsonRangeWriter(Writer writer, Map<String, String> processedInteractors,
                                 Map<Entity, Integer> processedParticipants, IncrementalIdGenerator idGenerator){
        this(writer, processedInteractors, processedParticipants);
        this.idGenerator = idGenerator;
    }

    /**
     * <p>write.</p>
     *
     * @param object a {@link psidev.psi.mi.jami.model.Range} object.
     * @throws java.io.IOException if any.
     */
    public void write(Range object) throws IOException {
        write(object, null);
    }

    /** {@inheritDoc} */
    public void write(Range object, Feature parent) throws IOException {
        // start object
        MIJsonUtils.writeStartObject(writer);
        // position
        MIJsonUtils.writeProperty("pos", RangeUtils.convertRangeToString(object), writer);
        // resulting sequence
        if (object.getResultingSequence() != null && object.getResultingSequence().getNewSequence() != null){
            MIJsonUtils.writeSeparator(writer);
            MIJsonUtils.writeProperty("resultingSequence", JSONValue.escape(object.getResultingSequence().getNewSequence()), writer);
        }

        Interactor interactor = null;
        Entity participant = null;
        if (object.getParticipant() != null && !(object.getParticipant().getInteractor() instanceof Complex)){
            interactor = object.getParticipant().getInteractor();
            participant = object.getParticipant();
        }
        else if (object.getParticipant() == null &&
                parent != null && parent.getParticipant() != null &&
                !(parent.getParticipant().getInteractor() instanceof Complex)){
           interactor = parent.getParticipant().getInteractor();
           participant = parent.getParticipant();
        }
        if (interactor != null){
            String[] extractedInteractorId =  MIJsonUtils.extractInteractorId(interactor.getPreferredIdentifier(), interactor);
            String key = extractedInteractorId[0]+"_"+extractedInteractorId[1];

            if (!this.processedInteractors.containsKey(key)){
                this.processedInteractors.put(key, key);
            }
            MIJsonUtils.writeSeparator(writer);
            MIJsonUtils.writeProperty("interactorRef", this.processedInteractors.get(key), writer);
        }
        if (participant != null){
            int id = 0;
            if (this.processedParticipants.containsKey(participant)){
                id = this.processedParticipants.get(participant);
            }
            else{
                id = getIdGenerator().nextId();
                this.processedParticipants.put(participant, id);
            }
            MIJsonUtils.writeSeparator(writer);
            MIJsonUtils.writeProperty("participantRef", Integer.toString(id), writer);
        }
        // end object
        MIJsonUtils.writeEndObject(writer);

    }

    /**
     * <p>Getter for the field <code>idGenerator</code>.</p>
     *
     * @return a {@link psidev.psi.mi.jami.json.IncrementalIdGenerator} object.
     */
    public IncrementalIdGenerator getIdGenerator() {
        if (idGenerator == null){
           idGenerator = new IncrementalIdGenerator();
        }
        return idGenerator;
    }

    /**
     * <p>Setter for the field <code>idGenerator</code>.</p>
     *
     * @param idGenerator a {@link psidev.psi.mi.jami.json.IncrementalIdGenerator} object.
     */
    public void setIdGenerator(IncrementalIdGenerator idGenerator) {
        this.idGenerator = idGenerator;
    }
}

@@ -3634,91 +3634,242 @@
     
-else if (object.getParticipant() == null &&%0A                parent != null && paren
+// This case branch takes into account too the cases that the feature hasn't selected a member of the complex participant. To avoid the viewer to%0A        // fail it will point to the whole complex cover the case%0A        else if (objec
 t.ge
@@ -3875,33 +3875,33 @@
 etParticipant() 
-!
+=
 = null &&%0A      
@@ -3910,18 +3910,34 @@
         
-!(
+parent != null && 
 parent.g
@@ -3955,47 +3955,20 @@
 nt()
-.getInteractor() instanceof Complex)
+ != null
 )%7B%0A
+ 
     
@@ -4020,32 +4020,33 @@
 etInteractor();%0A
+ 
            parti

Fix a problem to miJson writer. When a feature is connected with a participant that is a complex it wasn't adding the interactorRef and participantRef in the range, creating problems for the complex viewer to visualize this type of interaction.