package main

import (
	"fmt"
	"os"
	"bufio"
	"unicode"
    "bytes"
    "sort"
)


//---
type int_word_array []int_word

// Methods required by sort.Interface to sort structures of the type int_word.
func (s int_word_array) Len() int           { return len(s) }
func (s int_word_array) Less(i, j int) bool { return s[i].cpt > s[j].cpt } //(reverse sort)
func (s int_word_array) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }

type int_word struct {
	cpt  int
	word string
}
//---



func main() {

	words_map := map[string]int{}

	l_cnt := 0
	w_cnt := 0
	cpt_chars := 0
	inword := false
	var buf bytes.Buffer

	f, err := os.Open("../../shakespeare.txt", os.O_RDONLY, 0666)

	if err != nil {
		fmt.Printf("\nError => %s\n\n", err)
		os.Exit(1)
	}

	reader := bufio.NewReader(f) //Buffered reader

	for {
		c, _, err := reader.ReadRune() //"ReadRune": reads unicode chars
		cpt_chars++
		if err != os.EOF && err == nil {
			if c == '\n' {
				l_cnt++
			}

			if unicode.IsSpace(c) == false { //Scanner : filters out whitespace
				if inword == false {
					buf.Reset()
					buf.WriteRune(c)
					inword = true
					w_cnt++
				} else {
					buf.WriteRune(c)
				}
			} else if inword == true {

				if _, ok := words_map[buf.String()]; ok {
					words_map[buf.String()]++
				} else {
					words_map[buf.String()] = 1
				}

				//fmt.Printf("buf = (%s)\n", buf)
				inword = false
				buf.Reset()
			}

		} else { //EOF detected
			if err == os.EOF {
				break
			}
		} //end if (err=nil)
	} // end for (main loop)


	//---
	var words_map_size int = len(words_map)
	var int_words int_word_array
	int_words = make(int_word_array, words_map_size)
	var iw int_word

	int_words_index := 0
	for word, cpt := range words_map {
		//fmt.Printf("%d =\t\t%s\n", cpt, word)
		iw.cpt = cpt
		iw.word = word
		int_words[int_words_index] = iw
		int_words_index++
	}

	sort.Sort(int_words)

	for _, item := range int_words[0:10] {
		fmt.Printf("(%d,%s)\n", item.cpt, item.word)
    }
	//---

    //fmt.Printf("King freq : %d\n", words_map["King"])

}
