/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.lib.editor.codetemplates.textsync;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Group of text syncs that can be traversed by TAB (Shift-TAB) keys. ENTER may
 * be used to activate a special caret text sync.
 * <br/>
 * {@link TextRegionManager} can maintain multiple groups but only one of them
 * may be active at a given time.
 *
 * @author Miloslav Metelka
 */
public final class TextSyncGroup<I> {
    
    private TextRegionManager manager;
    
    private List<TextSync> textSyncs;
    
    private int activeTextSyncIndex = -1;

    /**
     * Client-specific information.
     */
    private I clientInfo;

    public TextSyncGroup(TextSync... textSyncs) {
        initTextSyncs(textSyncs.length);
        for (TextSync textSync : textSyncs)
            addTextSync(textSync);
    }
    
    public TextSyncGroup() {
        initTextSyncs(4);
    }

    private void initTextSyncs(int size) {
        this.textSyncs = new ArrayList<TextSync>(size);
    }
    
    /**
     * Get list of all text syncs managed by this group.
     *
     * @return non-null unmodifiable list of text syncs.
     */
    public List<TextSync> textSyncs() {
        return Collections.unmodifiableList(textSyncs);
    }
    
    public void addTextSync(TextSync textSync) {
        if (textSync == null)
            throw new IllegalArgumentException("textSync cannot be null");
        if (textSync.group() != null)
            throw new IllegalArgumentException("textSync " + textSync + // NOI18N
                    " already assigned to group " + textSync.group()); // NOI18N
        textSyncs.add(textSync);
        textSync.setGroup(this);
        
    }

    public void removeTextSync(TextSync textSync) {
        if (textSyncs.remove(textSync)) {
            textSync.setGroup(null);
        }
    }

    List<TextSync> textSyncsModifiable() {
        return textSyncs;
    }

    public TextRegionManager textRegionManager() {
        return manager;
    }
    
    void setTextRegionManager(TextRegionManager manager) {
        this.manager = manager;
    }

    public I clientInfo() {
        return clientInfo;
    }

    public void setClientInfo(I clientInfo) {
        this.clientInfo = clientInfo;
    }

    public TextSync activeTextSync() {
        return (activeTextSyncIndex >= 0 && activeTextSyncIndex < textSyncs.size())
                ? textSyncs.get(activeTextSyncIndex)
                : null;
    }

    public int activeTextSyncIndex() {
        return activeTextSyncIndex;
    }

    void setActiveTextSyncIndex(int activeTextSyncIndex) {
        this.activeTextSyncIndex = activeTextSyncIndex;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder(textSyncs.size() * 50 + 2);
        sb.append(super.toString());
        if (clientInfo != null) {
            sb.append(" ").append(clientInfo);
        }
        sb.append('\n');
        for (TextSync ts : textSyncs) {
            sb.append("  ").append(ts).append('\n');
        }
        return sb.toString();
    }

}
