using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;

using ms.aq.cview.util;

namespace ms.aq.cview.query {
    /*
     * represents selected 'tokens'
     * ie, clicked stuff goes in here
     * the type of a token is determined by its prefix.  
     * A prefix is encoded/decoded by PrefixDecoder
     */
    public class SelectionSets {
        /*
         * determines the aggregate function used on those situations that require it.
         */
        public AggregateFunctions Agg;
        public string ActiveTable;
        /*
         * Useful only for P1QueryFactory.  Probably a better way to do this.
         */
        public int ActiveSeries;
        
        /*
         * Should be a string that is a P[\d]+ in PrefixDecoder.
         * For example, range and series plot type is P1
         */
        public string PlotType {
            
            get { return ptype; }
            set {
                if (value != ptype) Sets.Clear();
                ptype = value;
            }
        }
        private Hashtable Sets = new Hashtable();

        private string ptype;
        /*
         * returns a list of all contained tokens.
         * prefixes are not included
         */
        public StringCollection GetAllTokens() {
            StringCollection rst = new StringCollection();
            foreach (object o in Sets.Keys) {
                StringCollection sc = (StringCollection)Sets[o];
                foreach(string s in sc)
                    rst.Add(s);
            }
            return rst;
        }
        /*
         * this used to assign an id to the stuff this selection sets hold.
         * should be the same if holds the same things, diff otherwise
         * this one isn't very good, but hopefully will hold up.
         */
        public string ComputeIdentifier() {
            long tmp = 0;
            foreach (object o in Sets.Keys) {
                StringCollection sc = (StringCollection)Sets[o];
                tmp+=o.GetHashCode();
                foreach (string s in sc)
                    tmp += s.GetHashCode(); 
            }
            tmp += ptype.GetHashCode();
            tmp += Agg.GetHashCode();
            tmp += DateTime.Now.GetHashCode();//and one to grow on
            return Math.Abs(tmp).ToString();
        }
        /*
         * returns all tokens with their prefix appended
         */
        public StringCollection GetAllTokensWithPrefixes() {
            StringCollection rst = new StringCollection();
            foreach (object o in Sets.Keys) {
                StringCollection sc = (StringCollection)Sets[o];
                foreach (string s in sc)
                    rst.Add(o+s);
            }
            return rst;
        }
        /*
         * given a prefix, return the tokens associated with that prefix
         */
        public StringCollection GetCollection(string prefix) {
            if (!Sets.ContainsKey(prefix))return new StringCollection();
            return (StringCollection)Sets[prefix];
        }
        /*
         * returns all contained prefixes
         */
        public ICollection GetPrefixes() {return Sets.Keys;}
        /*
         * returns all prefixes that start with the given prefix
         * returns an arraylist so it can be easily sorted
         */
        public ArrayList GetPrefixes(string prePrefix) {
            ArrayList rst = new ArrayList();
            foreach (object o in Sets.Keys) {
                string s = (string)o;
                if (s.StartsWith(prePrefix))
                    rst.Add(s);
            }
            return rst;
        }
        /*
         * returns all tokens whose prefix starts with the passed parameter
         */
        public ArrayList GetCollectionsByPrefix(string prePrefix) {
            ArrayList rst = new ArrayList();
            foreach (object o in Sets.Keys)
                if (o.ToString().StartsWith(prePrefix))
                    rst.Add(Sets[o]);
            return rst;
        }
        /*
         * add a new token
         */
        public void AddSelection(string prefix, string selection){
            if (!Sets.ContainsKey(prefix))
                Sets.Add(prefix, new StringCollection());
            StringCollection sc = (StringCollection)Sets[prefix];
            sc.Add(selection);
            Sets[prefix] = sc;
        }
        /*
         * add lots of new tokens
         */
        public void AddSelections(string prefix, StringCollection selections) {
            foreach (string s in selections)
                AddSelection(prefix, s);
        }
        /*
         * remove a token.
         * if that token is '__EVERYTHING__'
         * then all tokens for that prefix will be removed
         */
        public void RemoveSelection(string prefix, string selection) {
            if (!Sets.ContainsKey(prefix)) return;
            StringCollection sc = (StringCollection)Sets[prefix];
            if (selection == "__EVERYTHING__") sc.Clear();
            else sc.Remove(selection);           
            Sets[prefix] = sc;
        }

        public void RemoveSelectionsThatContain(string prefix, string substring) {
            if (!Sets.ContainsKey(prefix)) return;
            StringCollection sc = (StringCollection)Sets[prefix];
            StringCollection toRemove = new StringCollection();
            foreach (string s in sc)
                if (s.IndexOf(substring) > -1)
                    toRemove.Add(s);
            foreach (string s in toRemove)
                sc.Remove(s);
            Sets[prefix] = sc;
        }
    }
}
