﻿Globals.CollisionMatrixWindow = function(apiStore, selectedRows) {
    var rend = function(v, m, rec, row, col) {
        if (v && v.length > 0) {
            m.css = 'collision';
            var cssCollisions = [], 
                scriptCollisions = [];

            Ext.each(v, function(symbolInfo) {
                if (symbolInfo.category === "CSS style rules") {
                    cssCollisions.push(symbolInfo.name);
                } else {
                    scriptCollisions.push(symbolInfo.name);
                }
            });

            var cssText = '';
            var scriptText = '';

            if (cssCollisions.length > 0) {
                cssText = '<U>CSS:</U><br/>' + cssCollisions.join('<br/>');
            }

            if (scriptCollisions.length > 0) {
                scriptText = '<U>JavaScript:</U><br/>' + scriptCollisions.join('<br/>') + '<br/>';
            }

            m.attr = String.format('qtip="<b>{0} + {1}</b><br/>{2}{3}"',
                            rec.get('name'),
                            grid.store.getAt(col - 1).get('name'),
                            scriptText,
                            cssText);
            return v.length;
        }
    };
    
    var cols = [{
        width: 180,
        header: 'Framework',
        dataIndex: 'name',
        sortable: true,
        fixed: true,
        renderer: function(v, m, r) {
            m.css = r.get('id') + ' matrixNameColumn';
            m.attr = 'style="padding-left:30px"';
            
            // Append version number
            var apiRec = apiStore.query("id", r.get('id')).get(0);
            var ver = apiRec.get('version');
            if (!ver) {
                ver = apiRec.get('versions')[0].name || '';
            } 
            return v + ' ' + ver;
        }
    }];

    var fields = [{ name: 'name', type: 'string' }, 'id'];

    var initialRows = [];

    // Create columns and field definition for the matrix grid
    if (apiStore && selectedRows.length > 0) {
        Ext.each(selectedRows, function(index) {
            var record = apiStore.getAt(index);
            
            var id = record.get('id');

            cols.push({
                fixed: true,
                width: 25,
                dataIndex: id,
                id: id,
                tooltip: record.get('name'),
                align: 'center',
                sortable: false,
                renderer: rend
            });

            var rowValues = [];
            rowValues[0] = record.get('name');
            rowValues[1] = id;
            initialRows.push(rowValues);
            fields.push(id);
        });
    }

    var grid = new Ext.grid.GridPanel({
        enableHdMenu: false,
        cls: 'matrix',
        store: new Ext.data.SimpleStore({
            fields: fields,
            data: initialRows
        }),
        columns: cols
    });

    var win = new Ext.Window({
        title: 'Namespace collision matrix',
        height: 550,
        width: 780,
        modal: true,
        maximizable: true,
        layout: 'fit',
        items: grid
    });

    win.grid = grid;
    
    var collisionsDetected = false;
    
    win.scanForCollisions = function() {

        Ext.MessageBox.progress('Please wait', '', 'Analyzing...');
        var totalCells = initialRows.length * initialRows.length;
        var gridStore = win.grid.store;
        
        (function CompareFrameworks(currRowIndex, currCellIndex) {
            if (!gridStore.getAt(currCellIndex).get('symbols')) {
                var colId = fields[currCellIndex + 2];
                var rowId = fields[currRowIndex + 2];

                // HACK Make sure we don't treat different flavours of a library as a collision
                if (!rowId.match(colId) && !colId.match(rowId)) {
                    var progressNumber = (currCellIndex + 1 + (currRowIndex * initialRows.length)) / totalCells;
                    var r1, r2;
                    r1 = apiStore.query('id', colId).get(0);
                    r2 = apiStore.query('id', rowId).get(0);
                    
                    Ext.MessageBox.updateProgress(progressNumber,
                                                  'Analyzing...',
                                                  r1.get('name') +
                                                  ' - ' +
                                                  r2.get('name'));

                    var coll = GetCollisions(r1.get('symbols'),
                                             r2.get('symbols'));

                    if (r1.get('dependencies') ||
                        r2.get('dependencies')) {

                        var dependencyId = r1.get('dependencies') ||
                                           r2.get('dependencies');


                        var dependencySymbols = apiStore.getAt(apiStore.find('id', dependencyId)).get('symbols');

                        for (var i = coll.length - 1; i > 0; i--) {
                            Ext.each(dependencySymbols, function(o2) {
                                if (coll[i].name === o2.name) {
                                    coll.remove(coll[i]);
                                    return false;
                                }
                            });
                        }
                    }

                    gridStore.getAt(currRowIndex).set(fields[currCellIndex + 2], coll);
                    gridStore.getAt(currCellIndex).set(fields[currRowIndex + 2], coll);
                    
                    if (coll && coll.length > 0) {
                        collisionsDetected = true;
                    }
                }
            }
            
            if (currCellIndex < (initialRows.length - 1)) {
                currCellIndex++;
            }
            else {
                currRowIndex++;
                currCellIndex = 0;
            }

            if (currRowIndex < initialRows.length) {
                // Use defer to keep from hogging the UI
                CompareFrameworks.defer(10, null, [currRowIndex, currCellIndex]);
            } else {
                // Done
                Ext.Msg.hide();
                
                if (!collisionsDetected) {
                    Ext.Msg.alert('Done', 'No collisions detected!', win.close, win);
                }
            }
        })(0, 0);

        // Intersect the 2 arrays
        function GetCollisions(coll, coll2) {
            var collisions = [];

            if (coll && coll2) {
                Ext.each(coll, function(o1) {
                    Ext.each(coll2, function(o2) {
                        if (o1.name === o2.name) {
                            collisions.push(o1);
                        }
                    });
                });
            }

            return collisions;
        }
    };

    return win;
};

