using System;
using System.Collections.Generic;
using System.Collections;
using System.IO;
using System.Text;
using Spherical;
using Spherical.HTM;
namespace hcalc {

    public class WDB {
        private readonly string home = "C:\\WDB\\";
        private readonly string nameCil = "namer-cil.txt";
        private readonly string namePby = "namer-pby.txt";
        // segment 1  rank 1  points 2854
	    // 52.837778 -128.137778
	    // 52.841944 -128.137778
        string[] _tokens;
        char[] _delims;
        int _ct;
        Segment _segg = null;
        public class Segment {
            public int ID;
            public int rank;
            public int npoints;
            public List<Cartesian> points;
            // TODO: List<Int64Pair> htmCover;
        }
        // some external canvas object will reach into 
        // this object's coastlines and coundaries
        //
        // TODO: make a level of detail-specific hieararchy
        //
       
        internal List<Segment> boundaries;
        internal List<Segment> coastline;

        internal List<Segment> LOREScoastline;
        public void makeLowRes(){
            LOREScoastline = new List<Segment>();
           
            
            foreach (Segment segg in coastline){ 
                Segment newseg = new Segment();
                newseg.points = new List<Cartesian>();
                if (segg.rank == 1){
                    int i;
                    int n = segg.points.Count;
                    i = 0;
                    int k = 0;
                    Cartesian newp = new Cartesian(0.0, 0.0, 0.0, false); // Yes, I mean 0 vector
                    while(i < n){
                        k = 4;
                        do {
                            newp.Incr(segg.points[i++]);
                            k--;
                        } while(k > 0 && i < n);
                        newp.Normalize();
                        newseg.points.Add(newp);
                    }
                }
                LOREScoastline.Add(newseg);
            }
                        
        }
        private void rewind() {
            _ct = 0;
        }
        private void advance() {
            _ct++;
        }
        /// <summary>
        /// True, if there are any tokens left to parse. ismore() skips over white spaces
        /// </summary>
        protected bool ismore {
            get {
                while(_ct < _tokens.Length && _tokens[_ct].Length == 0) {
                    _ct++;
                }
                return _ct < _tokens.Length;
            }
        }
        private double getdouble() {
            double res;
            if(ismore) {
                res = double.Parse(_tokens[_ct].Trim());
                advance();
                return res;
            } else {
                return 0.0;
            }
        }

        private int getint() {
            int res;
            if(ismore) {
                res = int.Parse(_tokens[_ct].Trim());
                advance();
                return res;
            } else {
                return 0;
            }
        }

		private string getstring(){
			string res;
            if(ismore) {
                res = _tokens[_ct];
                advance();
                return res;
            } else {
                return null;
            }
		}

        private void parse(string s, List<Segment> listsegment) {
            _tokens = s.Split(_delims);
            _ct = 0;
            string word;
            
            while(ismore) {
                word = getstring();
                if(word.Equals("segment")) {
                    // segment 1  rank 1  points 2854
                    if(_segg != null) {
                        listsegment.Add(_segg);
                    }
                    _segg = new Segment();
                    _segg.ID = getint();
                    word = getstring();
                    _segg.rank = getint();
                    word = getstring();
                    _segg.npoints = getint();
                    _segg.points = new List<Cartesian>(_segg.npoints);
                } else {
                    rewind();
                    double lat = getdouble();
                    double lon = getdouble();
                    _segg.points.Add(new Cartesian(lon, lat));
                }   
            }
        }
        public WDB() {
            coastline = new List<Segment>(6000);
            boundaries = new List<Segment>(230);
            
            string coastlineFile = home + nameCil;
            string boundaryFile = home + namePby;
            StreamReader rs = null;
            String s;
            
            
// -------------------------------------------------------------------           
            try {
                rs = new StreamReader(coastlineFile);
            } catch {
                rs = null;
            }
            if (rs != null){
                _delims = " \t\n\r,".ToCharArray();
                while(!rs.EndOfStream){
                    // 52.837778 -128.137778
                    // 52.841944 -128.137778
                    s = rs.ReadLine();
                    parse(s, coastline);
                }
                // _segg.ComputeCover()
                coastline.Add(_segg);
            }
            _segg = null;
        // -------------------------------------------------------------------           
            try {
                rs = new StreamReader(boundaryFile);
            } catch {
                rs = null;
            }
            if (rs != null){
                _delims = " \t\n\r,".ToCharArray();
                while(!rs.EndOfStream){               
                    // 52.837778 -128.137778
                    // 52.841944 -128.137778
                    s = rs.ReadLine();
                    parse(s, boundaries);
                }
                boundaries.Add(_segg);
            }
        }
    }
}
