package eu.toldi.rss;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;

import javax.swing.tree.DefaultMutableTreeNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Ez egy olyan hírcsatorna,amelyet több hírcsatorna összessége képez.
 */
@XStreamAlias("feedGroup")
public class FeedGroup extends Feed {
    /**
     * A hírcsatornák listája
     */
    List<Feed> feedList = new ArrayList<Feed>();
    /**
     * A csoport cikkjeinek listája
     */
    @XStreamOmitField
    List<Article> articleList = new ArrayList<Article>();

    public FeedGroup(String name){
        super(name);
    }

    /**
     * Hírcsatorna hozzáadása a csoporthoz
     * @param feed hozzáadandó hírcsatorna
     * Megjegyzés: Meglévő csatorna nem adható hozzá mégegyszer
     */
    public void addFeed(Feed feed){
        if(!feedExists(feed)) {
            feedList.add(feed);
            for (int i = 0; i < feed.getArticleCount(); i++) {
                articleList.add(feed.get(i));
            }
        }
    }

    /**
     * Ellenőrzi,hogy a megadott hírcsatorna metalálható-e benne
     * @param f az ellenőrizendő csatorna
     * @return logikai érték az alapján,hogy a csatorna megtalálható-e a csoportban
     * Megjegyzés: Csak abban az esetben tér vissza igazzal,ha a két objektum megegyezik egy a csoportban találhatóval
     */
    public boolean feedExists(Feed f){
        for (int i = 0; i < feedList.size(); i++) {
            if(f == feedList.get(i))
                return true;
        }
        return false;
    }

    /**
     * @see Feed#get(int) 
     */
    @Override
    public Article get(int i) {
        return articleList.get(i);
    }

    /**
     * @see Feed#updateFeed()
     * @throws IOException
     */
    @Override
    public void updateFeed() throws IOException {
        if(articleList == null)
            articleList = new ArrayList<Article>();
        for (Feed f:feedList) {
            f.updateFeed();
            for (int i = 0; i < f.getArticleCount(); i++) {
                articleList.add(f.get(i));
            }
        }
    }

    /**
     * @see Feed#getArticleCount()
     * @return
     */
    @Override
    public int getArticleCount() {
        int result = 0;
        for (Feed f:feedList) {
            result += f.getArticleCount();
        }
        return result;
    }

    /**
     * @see Feed#getTreeNode()
     * @return
     */
    @Override
    public DefaultMutableTreeNode getTreeNode() {
        DefaultMutableTreeNode folder = super.getTreeNode();
        for (Feed f: feedList) {
            folder.add(f.getTreeNode());
        }
        return folder;
    }

    /**
     * Hírcsatorna törlése a csoportból
     * @param feed a törlendő hírcsatorna
     * Megjegyzés: Ez törli az össze a csatornához tartozó cikket.
     */
    public void removeFeed(Feed feed){
        boolean found = false;
        for (int i = 0; i < feedList.size(); i++) {
            //Csak ha PONTOSAN megegyezik
            if(feedList.get(i) == feed){
                feedList.remove(i);
                found =true;
                break;
            }
        }
        if(found){
            List<Article> similar = new ArrayList<Article>( articleList );
            List<Article> different = new ArrayList<Article>();
            different.addAll( articleList );
            different.addAll( feed.getArticleList() );

            similar.retainAll( feed.getArticleList() );
            different.removeAll( similar );
            articleList = different;
        }
    }
    /**
     * Egy hírcsatorna áthelyezése a listában. Átrendezésre használatos.
     * @param f az áthelyezendő hírcsatorna
     * @param index a hírcsatorna új helye
     */
    public void setLocation(Feed f,int index){
        feedList.remove(f);
        feedList.add(index,f);
    }

}
