package edu.sc.seis.sod.channelGroup;

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

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import edu.sc.seis.seisFile.fdsnws.stationxml.Channel;
import edu.sc.seis.sod.model.station.ChannelGroup;


public class OrientedSiteRule extends SiteChannelRule {

    public OrientedSiteRule(String[] sites, char[] orientations) {
        this.siteCodes = sites;
        this.orientations = orientations;
    }

    public OrientedSiteRule(Element config) {
        NodeList childNodes = config.getChildNodes();
        int orientIndex=0;
        for(int counter = 0; counter < childNodes.getLength(); counter++) {
            Node node = childNodes.item(counter);
            if(node instanceof Element) {
                Element nodeEl = (Element)node;
                String tagName = nodeEl.getTagName();
                if (tagName.equals("orient")) {
                    siteCodes[orientIndex] = nodeEl.getAttribute("site");
                    orientations[orientIndex] = nodeEl.getAttribute("orientation").charAt(0);
                    orientIndex++;
                }
            }
        }
    }
    
    public List<ChannelGroup> acceptable(List<Channel> chanList, List<Channel> failures) {
        List<ChannelGroup> out = acceptable(null, chanList, failures);
        return out;
    }

    List<ChannelGroup> acceptable(Channel first, List<Channel> chanList, List<Channel> failures) {
        List<ChannelGroup> out = new ArrayList<ChannelGroup>();
        if (first != null) {
            Channel second = null;
            Channel third = null;
            for (Channel chan : chanList) {
                if (orientations[1] == chan.getChannelCode().charAt(2) && siteCodes[1].equals(chan.getLocCode())) {
                    second = chan;
                }
                if (orientations[2] == chan.getChannelCode().charAt(2) && siteCodes[2].equals(chan.getLocCode())) {
                    third = chan;
                }
            }
            if (second != null && third != null) {
                out.add(new ChannelGroup(new Channel[] {first, second, third}));
                chanList.remove(second);
                chanList.remove(third);
            } else {
                failures.add(first);
            }
        }
        if (chanList.size() > 2) {
            Channel nextFirst = null;
            for (Channel c : chanList) {
                if (orientations[0] == c.getChannelCode().charAt(2) && siteCodes[0].equals(c.getLocCode())) {
                    nextFirst = c;
                    chanList.remove(nextFirst);
                    break;
                }
            }
            if (nextFirst != null) {
                out.addAll(acceptable(nextFirst, chanList, failures));
            } else {
                failures.addAll(chanList);
                chanList.clear();
            }
        } else {
            failures.addAll(chanList);
            chanList.clear();
        }
        return out;
    }
    
    String[] siteCodes =  new String[3];
    char[] orientations = new char[3];
}
