DNow.GeographyDialog = Class.create( aw.ui.Dialog, {

    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
                        }
                    });
                }
            }
        }

        this._renderButton( 'OK', this._onSelectGeography.bind( this ) );
        this._renderButton( 'Cancel', this.close.bind( this ) );

        return this.canvas;
    },

    _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.close( );
            }
        }.bind( this, geoCollection ) );
    },

    _local_templates: {
        'ui': new Template(
            '<div class="geographyTree"></div>' + 
            '<div class="geographyHelp">Select one or more geographies from the list at the left and click OK when done.</div>')
    },

    EVENTS: ['ongeographyselected'],

    VALID_PROPERTIES: ['title','closeable','content','moveable','cssClass','componentBus','geoCollection'],

    CLASS_NAME: 'DNow.GeographyDialog'
});
