/*
Created by Benedict Wright
*/


/// <reference path="FDParser.ts" />
/// <reference path="resources/jquery.d.ts" />
module FD {
   export class JSONParser extends FDParser {

        private alreadyParsed: String[];

        constructor(debug: Boolean) {
            super(debug);
            this.alreadyParsed = [];

        }

        //@params
        //json: json encoded Data
        // expected Format: Array of root elements (even if only 1 root)
        public parse() {

            for (var elem in <any>this.rawData) {
                this.parseElement(this.rawData[elem], "", null);
            }

        }

        //creates a new Node or returns an existing one with given unique identifier
        private createNode(identifier: string): FDNode {
            for (var node in this.allNodes) {
                if (this.allNodes[node].uniqueId == identifier) {
                    return this.allNodes[node];
                }
            }
            var newNode = new FDNode();
            newNode.setUniqueId(identifier);
            this.addNode(newNode);
            return newNode;
        }

        private notYetParsed(identifier: string): Boolean {
            for (var s in this.alreadyParsed) {
                if (this.alreadyParsed[s] == identifier) {
                    return false;
                }
            }
            return true;
        }

        private parseElement(root: any, depth: String, parent: FDNode) {
            
            var current = this.createNode(root[this.uId]);

            if (this.notYetParsed(current.getUniqueId())) {
                //debugPrinter.print(depth + root[this.uId], this.debug);
                if (parent == null) {
                    this.addRootNode(current);
                } else {

                    //set childs parent

                    parent.addChild(current);

                    current.setParent(parent);
                }
            }
            this.alreadyParsed.push(current.getUniqueId());
            //add data to the node
            for (var key in root) {
                if (key != this.uId && key != this.childrenId && key != this.siblingId) {
                    current[key] = root[key]
            }
            }

            //parse children
            for (var elem in root[this.childrenId]) {
                this.parseElement(root[this.childrenId][elem], depth + "    ", current);
            }

            //parse siblings
            for (var elem in root[this.siblingId]) {
                //CAUTION do not parse same node multiple times (endles loop!!)
                var siblingNode = this.createNode(root[this.siblingId][elem][this.uId]);

                current.addSibling(siblingNode);

                if (this.notYetParsed(siblingNode.getUniqueId())) {

                    this.parseElement(root[this.siblingId][elem], depth, parent);
                }


            }

        }

    }
}
