DNow.IndexBaseDialog = Class.create(aw.ui.Dialog, {

    currentBranch: null,

    treeDef: null,

    geoCollection: null,

    _customGeographies: [],

    _geographyTree: null,

    initialize: function (properties, events) {
        this.geoCollection = null;
        this.inheritCSS = true;

        this._customGeographies = [];
        this._geographyTree = null;

        Object.extend(properties, {
            'title': 'Select Geography'
        });

        aw.ui.Dialog.prototype.initialize.apply(this, arguments);
    },

    draw: function () {
        aw.ui.Dialog.prototype.draw.apply(this);

        var contents = this.canvas.down('div.contents');
        if (contents) {
            contents.update(this._local_templates['ui'].evaluate({}));

            var tree = contents.down('div.geographyTree');
            if (tree) {
                var gm = this.componentBus.getComponentReferences('aw.GeographyManager');
                if ((gm) && (gm.length > 0)) {
                    gm = gm[0];

                    var selectedNodeKeys = [];
                    if ((this.geoCollection) && (this.geoCollection.geos) && (this.geoCollection.geos.length > 0)) {
                        var geo = null, centroid = null, radius = null, centroidIndex = null;
                        for (var i = 0, len = this.geoCollection.geos.length; i < len; ++i) {
                            geo = this.geoCollection.geos[i];
                            if (geo.derivesFrom('aw.Geography.Standard')) {
                                selectedNodeKeys.push(geo.shortGeoName + ":" + geo.geoKey);
                            }
                        }
                    }

                    //var customNodes = this._buildCustomGeographyNodes( this.geoCollection );

                    this._geographyTree = new aw.ui.Tree({
                        'container': tree,
                        'componentBus': this.componentBus,
                        /*
                        'nodes': [{
                        'key': 'CUSTOM',
                        'label': 'Custom Radii/Drivetimes',
                        'type': ((customNodes) && (customNodes.length > 0)) ? 'branch' : 'leaf',
                        'selectable': false,
                        'actions': [{
                        'label': 'Create',
                        'callback': this._onCreateRadiiClicked.bind( this )
                        }],
                        'children': customNodes
                        }],
                        */
                        'baseRequest': {
                            'cn': 'SRC.Web.Client.Handler.AllocateHandler|' + gm.allocateDataset.variant,
                            'service': 'geographyTree',
                            'k': selectedNodeKeys
                        }
                    }, { 'onselectionchanged': this._selectionChanged });
                }
            }
        }

        this._renderButton('OK', this._onSelectGeography.bind(this));
        this._renderButton('Cancel', this.hide.bind(this));

        req = { 'cn': 'SRC.Web.Client.Handler.AllocateHandler|' + gm.allocateDataset.variant,
            'service': 'geographyTree'
        }
        this.request(req, function (dataset, response) { this.treeDef = response.payload.tree; }.bind(this));

        return this.canvas;
    },



    _selectionChanged: function (tree, selection) {
        //Only items under one branch may be selected at a time
        if (selection == null)
            return;
        if (this.currentBranch == null)
            this.currentBranch = selection.key.split(":")[0];

        //If the new selection's branch does not match the current branch, 
        //1. clear the tree
        //2. update the current branch
        //3. select the new selection
        if (selection.key.indexOf(this.currentBranch) == -1) {
            tree.clearSelection();
            this.currentBranch = selection.key.split(":")[0];
            tree.selectNodeByKey(selection.key);
        }
    },

    _getCustomGeographyByKey: function (key) {
        if ((!key) || (!this._customGeographies) || (!this._customGeographies.length > 0))
            return null;

        var centroid = null, geoClass = null;
        var geos = [];

        for (var i = 0, len = this._customGeographies.length; i < len; ++i) {
            centroid = this._customGeographies[i];
            geoClass = (centroid.type == 'aw.Geography.Radius') ? aw.Geography.Radius : aw.Geography.Drivetime;
            if (centroid.key == key) {
                if ((centroid.radii) && (centroid.radii.length > 0)) {
                    for (var j = 0; j < centroid.radii.length; j++) {
                        geos.push(new geoClass(null, centroid.radii[j].name, centroid.radii[j].label, centroid.radii[j].radius, centroid.x, centroid.y, centroid.radii[j].units));
                    }
                }
            } else {
                if ((centroid.radii) && (centroid.radii.length > 0)) {
                    for (var k = 0; k < centroid.radii.length; k++) {
                        if (centroid.radii[k].key == key)
                            geos.push(new geoClass(null, centroid.radii[k].name, centroid.radii[k].label, centroid.radii[k].radius, centroid.x, centroid.y, centroid.radii[k].units));
                    }
                }
            }
        }

        return geos;
    },

    _buildCustomGeographyNodes: function (geoCollection) {
        this._customGeographies = [];
        var centroids = [], customNodes = [], selectedNodeKeys = [];
        if ((geoCollection) && (geoCollection.geos) && (geoCollection.geos.length > 0)) {
            var geo = null, centroid = null, radius = null, centroidIndex = null;
            for (var i = 0, len = geoCollection.geos.length; i < len; ++i) {
                geo = geoCollection.geos[i];
                if (geo.derivesFrom('aw.Geography.Radius')) {
                    centroid = geo.getCentroid();
                    radius = { 'key': this.getId(), 'name': geo.name, 'label': (geo.getRadius() + ' ' + geo.getUnits() + ' ' + (geo.CLASS_NAME == 'aw.Geography.Drivetime' ? 'Drivetime' : 'Radius')), 'radius': geo.getRadius(), 'units': geo.getUnits() };
                    centroidIndex = geoCollection._containsCentroid(this._customGeographies, geo.CLASS_NAME, centroid);
                    if (centroidIndex < 0)
                        this._customGeographies.push({ 'key': this.getId(), 'name': geo.name, 'type': geo.CLASS_NAME, 'x': centroid.x, 'y': centroid.y, 'radii': [radius] });
                    else
                        this._customGeographies[centroidIndex].radii.push(radius);
                }
            }
        }

        if ((this._customGeographies) && (this._customGeographies.length > 0)) {
            var c = null;
            for (var j = 0; j < this._customGeographies.length; j++) {
                c = {
                    'key': 'CUSTOM:' + this._customGeographies[j].key,
                    'parentKey': 'CUSTOM',
                    'label': this._customGeographies[j].name,
                    'type': 'branch',
                    'selectable': true,
                    'selected': true,
                    'children': []
                };

                for (var k = 0; k < this._customGeographies[j].radii.length; k++) {
                    c.children.push({
                        'key': 'CUSTOM:' + this._customGeographies[j].radii[k].key,
                        'label': this._customGeographies[j].radii[k].label,
                        'type': 'leaf',
                        'selectable': true
                    });
                }

                customNodes.push(c);
            }
        }

        return customNodes;
    },

    _onCreateRadiiClicked: function () {
        new DNow.CustomRadiiDialog({ 'componentBus': this.componentBus }, { 'onpointscreated': function (geoCollection) {
            if (this._geographyTree) {
                this._geographyTree.removeChildNodesByKey('CUSTOM');
                this._geographyTree.addNodes(this._buildCustomGeographyNodes(geoCollection));
            }
            this.show();
        }.bind(this)
        });
        this.hide();
    },

    _onSelectGeography: function () {
        if (!this._geographyTree)
            return;

        var gm = this.componentBus.getComponentReferences('aw.GeographyManager');
        if ((gm) && (gm.length > 0))
            gm = gm[0];
        else
            return;

        var geoCollection = new aw.GeographyCollection();
        var labels = [];
        var keyFrags = [];

        var selectedNodes = this._geographyTree.getSelectedNodes();

        if ((selectedNodes) && (selectedNodes.length > 0)) {
            for (var i = 0, len = selectedNodes.length; i < len; ++i) {
                keyFrags = selectedNodes[i].key.split(':');
                if (keyFrags[0] == 'CUSTOM') {
                    var geos = this._getCustomGeographyByKey(keyFrags[1]);
                    if ((geos) && (geos.length > 0)) {
                        for (var j = 0; j < geos.length; j++) {
                            geoCollection.addGeography(geos[j]);
                        }
                    }
                } else {
                    geoCollection.addGeography(new aw.Geography.Standard(null, selectedNodes[i].label, selectedNodes[i].label, keyFrags[0], ((keyFrags.length > 1) ? keyFrags[keyFrags.length - 1] : '*'), gm.allocateDataset.key));
                }
            }
        }

        geoCollection.generateLabel();

        var req = {
            'cn': 'SRC.Web.Client.Handler.AllocateHandler|' + gm.allocateDataset.variant,
            'service': 'computeBounds'
        };

        Object.extend(req, geoCollection.getGeographyDefinition());
        this.request(req, function (geoCollection, classname, o) {
            if ((!o) || (!o.payload))
                return;

            var count = o.payload.count;
            if (count > 5000) {
                new aw.ui.Dialog.Error({ 'title': 'Error', 'content': 'You may not select more than 5,000 individual geographies.' });
            } else if (count < 1) {
                new aw.ui.Dialog.Error({ 'title': 'Error', 'content': 'You must select at least one geography.' });
            } else {
                geoCollection.setGeographyCount(count);
                this.triggerEvent('ongeographyselected', geoCollection, o.payload.minx, o.payload.miny, o.payload.maxx, o.payload.maxy);
                this.hide();
            }
        }.bind(this, geoCollection));
    },

    _local_templates: {
        'ui': new Template(
            '<div class="geographyTree"></div>' +
            '<div class="geographyHelp">Choose what type of geography you want to build your Index Base from. Then click OK. </div>')
    },

    getLongGeoName: function (shortGeoName) {
        for (i = 0; i < this.treeDef.length; i++) {
            if (this.treeDef[i].key.indexOf(shortGeoName) != -1)
                return this.treeDef[i].label;
        }
    },

    EVENTS: ['ongeographyselected'],

    VALID_PROPERTIES: ['title', 'closeable', 'content', 'moveable', 'cssClass', 'componentBus', 'geoCollection'],

    CLASS_NAME: 'DNow.IndexBaseDialog'
});
