Ext.ns('OPSWAT');


Ext.override(Ext.XTemplate, {
	exists: function(o, name) {
		return o.hasOwnProperty(name);
	}
});


//something weird is going on with the first record (Antiphishing), here's
//a workaround
bug_retrievedWeirdo = false;
var disableCache	= true;


Ext.onReady(function(){

/******************************************************************
	 * product browser area
	 *
	 *
	 **/
	
	//create the text box
	
	
	var searchBox = new Ext.form.TextField({
        name: 'search',
		renderTo: 'stringSearch',
		emptyText: 'Search Products...',
		width: 316,
        listeners: {
            specialkey: function(field, e){
                // e.HOME, e.END, e.PAGE_UP, e.PAGE_DOWN,
                // e.TAB, e.ESC, arrow keys: e.LEFT, e.RIGHT, e.UP, e.DOWN
                if (e.getKey() == e.ENTER) {
					//yes, this is a hack, by removing focus we trigger the change handler
					document.getElementById('filterBtn').focus();
					searchBox.focus();
                }
            }
        }
	});
	
	
	var absform = new Ext.form.FormPanel({
    defaultType: 'textfield',
    items: [searchBox,{
		boxLabel: 'Identified',
		id: 'oesisok_identified_cb',
		name: 'oesisok_identified',
		xtype: 'checkbox',
		renderTo: 'ok0',
		value: 0,
		checked: true
		
	},{
		labelSeparator: '',
		boxLabel: 'Certified',
		id: 'oesisok_certified_cb',
		name: 'oesisok_certified',
		xtype: 'checkbox',
		checked: true,
		value: 1,
		renderTo: 'ok1'
	}, {
		labelSeparator: '',
		id: 'oesisok_gold_cb',
		boxLabel: 'Gold Certified',
		name: 'oesisok_gold',
		xtype: 'checkbox',
		checked: true,
		value: 2,
		renderTo: 'ok2'
	}]
});

	
	function FilterHelper(){
		var me = this;
		
		me.filterSettings = {};
		
		me.reset = function(){
			for (key in me.filterSettings){
				delete me.filterSettings[key];
			}
		},
		
		me.delParam = function(keyname){
			if (me.filterSettings[keyname]){
				delete me.filterSettings[keyname];
			}
		},
		
		//values should be treated as an array
		//strict mode enforces strict ^/$ regexp matching
		me.addParam = function(key, values, strictMode){
			strictMode = strictMode || false;
			
			if (values.length == 0){
				me.delParam(key);
			}else{
				var delimiter = '|';
				var re = '';
				
				if (strictMode){
					delimiter = '$|^';
				}

				var re = values.join(delimiter);
				if (strictMode){
					re = '^' + re + '$';
				}
				
				me.filterSettings[key] = new RegExp(re, 'i');
			}
		},
		
		me.doFilter = function(item){
			
			/**
			 * New code takes into consideration that the OKLevel is an AND
			 * operative
			 */
			
			
			if (me.filterSettings['OKLevel']){
				var dataval = item.data['OKLevel'] + '';
				
				if (!dataval.match(me.filterSettings['OKLevel'])){
					return false;
				}
			}
			
			if (me.filterSettings['Vendor_Id']){
				var dataval = item.data['Vendor_Id'] + '';
				
				if (!dataval.match(me.filterSettings['Vendor_Id'])){
					return false;
				}
			}
			
			if (me.filterSettings['Product_Name']){
				var dataval = item.data['Product_Name'] + ' ' + item.data['Vendor_Name'];
				if (!dataval.match(me.filterSettings['Product_Name'])){
					return false;
				}
			}
			
			return true;
		}
	};
	
	var Filterer = new FilterHelper();

	OPSWAT.ProductDetail = Ext.extend(Ext.Panel, {
		tplMarkup: [
			'<table class="productInfoPanel">',
				'<tr width="110">',
					//1st column, certification badge
					'<td rowspan="2">',
						'<tpl for="certifications.OESISOK">',
							'<img src="pb_oesisok_certlevel{level}.png" />',
						'</tpl>',
					'</td>',
					//2nd column, product name area
					'<td colspan="3">',
						'<div class="productName">{ProductName} ({Version})</div>',
						'<div class="vendorName">{Vendor}</div>',
					'</td>',
				'</tr>',
				//2nd row, all the stat area junk
				'<tr>',
					//2nd row, 1st column
					'<td width="350">',
						//display junk for identified products
						'<tpl for="certifications.OESISOK">',
							'<tpl if="level==0">',
								'<p>',
									'"Identified" Level certification can be detected but may have limited feature support with various 3rd party vendors.',
								'</p>',
							'</tpl>',
							//display junk for certified products
							'<tpl if="level==1">',
								'<p>',
									'"Certified" Level certification indicates the product is interoperable with the following vendors:',
								'</p><br />',
								'<img src="pb_vendorlist_certlevel1.gif" />',
							'</tpl>',
							//display junk for gold products
							'<tpl if="level==2">',
								'<p>',
									'Gold Certification indicates the product is interoperable with the maximum number of leading market vendors:',
								'</p><br />',
								'<img src="pb_vendorlist_certlevel2.gif" />',
							'</tpl>',
						'</tpl>',
					'</td>',
					//2nd row, 2nd column -- oesis ok junk
					'<td width="200">',
						'<tpl for="certifications.OESISOK">',
							'<tpl if="level &gt; 0">',
								'<div class="subHead2">OESIS OK Info</div>',
								'<div class="subHead3">Certified Date</div>',
								'<p>{date}</p><br />',
								'<div class="subHead3">Certified OS</div>',
								'<tpl for="os">',
									'<p>{.}</p>',
								'</tpl>',
							'</tpl>',
						'</tpl>',
					'</td>',
					//2nd row, 3rd column -- other certification junk
					'<td width="200">',
						//declare some vars for certifications so js doesn't crash
						'{[WestCoastLab_Level=""]}',
						'{[ICSA_Level=""]}',
						'{[VB100_Level=""]}',
						'{[AVComparitives_Level=""]}',

						//table to house av certs, adding table just for layout
						//purposes
						'<tpl if="certCount &gt; 0">',
							'<tpl if="OESISOK_Level &gt; 0">',
								'<div class="subHead2">Other Certifications</div>',
								'<table class="invisibleGrid">',
									'<tr>',
										'<tpl if="WestCoastLab_Level &gt; 0">',
											'<td width="56">',
												'<img src="pb_oesisok_othercert_wcl.png" />',
											'</td>',
										'</tpl>',
										'<td style="padding-left: 5px;">',
											'<tpl if="ICSA_Level &gt; 0">',
												'<p><img src="pb_oesisok_circlecheckmark.png" /> ICSA Labs</p>',
											'</tpl>',
											'<tpl if="VB100_Level &gt; 0">',
												'<p><img src="pb_oesisok_circlecheckmark.png" /> VB 100</p>',
											'</tpl>',
											'<tpl if="AVComparitives_Level &gt; 0">',
												'<p><img src="pb_oesisok_circlecheckmark.png" /> AV Comparitives</p>',
											'</tpl>',
										'</td>',
									'</tr>',
								'</tpl>',
							'</tpl>',
						'</table>',
					'</td>',
				'</tr>',
			'</table>'
		],
		
		oesisMarkup: [
			'<table class="productInfoPanel">',
				'<tr>',
				'</tr>',
			'</table>'
		],
		
		
		startingMarkup: 'Select an entry for additional details.',
	
		initComponent: function() {
			this.tpl = new Ext.XTemplate(this.tplMarkup);
			this.oesistab = new Ext.XTemplate(this.tab1)
			Ext.apply(this, {
				bodyCssStyle: 'product-detail-panel',
				html: this.startingMarkup
			});
			// call the superclass's initComponent implementation
			OPSWAT.ProductDetail.superclass.initComponent.call(this);
		},
		// add a method which updates the details
		updateDetail: function(data) {
			this.tpl.overwrite(this.body, data);
		}
	});
	// register the App.VirusDetail class with an xtype of VirusDetail
	Ext.reg('productdetail', OPSWAT.ProductDetail);
	
	
	var productTypeStore = new Ext.data.Store({
		proxy:  new Ext.data.HttpProxy({  
			url: portal_url + '/productlist/producttypes',
			method: 'GET',
			disableCaching: disableCache
		}),
		
		
		reader: new Ext.data.ArrayReader({
			fields: [ 'id', 'name' ],
			idIndex: 0
		})
        
    });
	
	productTypeStore.load();
	
	
	
	//this store handles data for each category...might have been
	//smarter to just put this in productTypeStore...hmmm
	var intermediaryStore = new Ext.data.Store({
	
		proxy:  new Ext.data.HttpProxy({  
			url: portal_url + '/productlist/productquery',
			method: 'GET',
			disableCaching: disableCache
		}),
		
        reader: new Ext.data.JsonReader({
			root: 'Data',
			id: 'id'
		},[
			{name: 'id'},
			{name: 'Products'},
			{name: 'Vendors'}
		])
		
	})
	
	
    var productTypeSelectionModel   = new Ext.grid.RowSelectionModel({singleSelect: true});
    var vendorSelectionModel        = new Ext.grid.RowSelectionModel();
    var productSelectionModel       = new Ext.grid.RowSelectionModel({singleSelect: true});
	
    var vendorStore = new Ext.data.Store({

		proxy:  new Ext.data.HttpProxy({  
			url: portal_url + '/productlist/productquery',
			method: 'GET'
		}),
		
        reader: new Ext.data.ArrayReader({
			fields: [ 'id', 'name' ],
			idIndex: 0
		})
    });
    
    var productStore = new Ext.data.Store({
        reader: new Ext.data.ArrayReader({
			fields: ['Category_Id', 'Vendor_Id', 'Product_Id', 'Product_Name', 'OKLevel', 'Vendor_Name'],
			idIndex: 0
        }),
		sortInfo: {
			field: 'Product_Name',
			direction: 'ASC' // or 'DESC' (case sensitive for local sorting)
		}
    });
    
    
    /**************************************************************************
     * Event handlers and functions here
     **************************************************************************/
    
	function runFilters(skipVendors){
		skipVendors = skipVendors||false;
		
		//vendorStore.suspendEvents();
		
		//filter product store
		productStore.filterBy(Filterer.doFilter);
		
		//filter vendors
		if (!skipVendors){
			var uniqueVendors = productStore.collect( 'Vendor_Id', false, false)
			
			var re = uniqueVendors.join('$|^');
			re = '^' + re + '$';
			
			vendorStore.filter('id', new RegExp(re));
		}
		
		//vendorStore.resumeEvents();
	}
	
	
	function updateVendorsAndProducts(store, recs, opts){
		var recId = opts.params.c;
		
		if (recs){
			var record 		= intermediaryStore.getById(recId);
			var vendorRec   = record.data['Vendors'];
			var productRec  = record.data['Products'];
			
			vendorStore.loadData(vendorRec);
			productStore.loadData(productRec);
			
			//apply filters
			runFilters();
				
		}
        
        Ext.getCmp('col2').getGridEl().unmask();
		
	}
	
    function updateVendorColumn(sm, rowIndex, typeRec){
        //load up the vendor box
		var id      = typeRec.data['id'];
        var recid   = intermediaryStore.find('id', id);

		var options = {params: {c:id}, add: true};
		
		Filterer.delParam('Vendor_Id');
		
		if(recid == -1 || ( bug_retrievedWeirdo == false && id == 1)){
			if (id == 1){
				bug_retrievedWeirdo = true;
			}
            Ext.getCmp('col2').getGridEl().mask('Loading...');
			intermediaryStore.load(options);
		}else{
			updateVendorsAndProducts(intermediaryStore, {}, options);
		}
		
    }
    
    function vendorSelect(sm){
        //filter whatever is selected. If nothing selected, select all.
        
        var selectedRecs = sm.getSelections();
        var vendors 	 = new Array()
        
		var recLen = selectedRecs.length;

		if (recLen == 0){
			vendorStore.each(function(rec){
				vendors.push(rec.data.id);
			});
		}else{
			for (i = 0; i < recLen; i++){
			    vendors.push(selectedRecs[i].data.id)
			}
		}

		Filterer.addParam('Vendor_Id', vendors, true);

        runFilters(true);
    }
	
	function productRenderer(value, meta, record){
		switch (record.data['OKLevel']){
			case 0:
				meta.css = "identified_certlevel";
				return value;
				break;
			case 1:
				meta.css = "normal_certlevel";
				return value;
				break;
			case 2:
				meta.css = "gold_certlevel";
				return value;
				break;
			
		}
		
		return value;
    }
	
	function populateDetails(value, meta, record){
        Ext.getCmp('productDetails').getEl().mask('Loading...');
		var conn = new Ext.data.Connection();
		conn.request({
			url: portal_url + '/productlist/productdetails',
			method: 'GET',
			disableCaching: disableCache,
			params: {
				pid: record.data["Product_Id"]
			},
			success: function(responseObject) {
				var jsonData = Ext.util.JSON.decode(responseObject.responseText);
				Ext.getCmp('productDetails').updateDetail(jsonData);
                Ext.getCmp('productDetails').getEl().unmask();
				
			},
			 failure: function() {
				Ext.Msg.alert('Status', 'Unable to display product details, please try again later.');
                Ext.getCmp('productDetails').getEl().unmask();
			 }
		});
	}
	
	function searchCategories(){
		
		//get checkboxes (yeah yeah this needs to be consolidated somewhere)
		boxes = ['oesisok_identified_cb', 'oesisok_certified_cb', 'oesisok_gold_cb'];
		
		var checkedValues = [];
		for (var i=0, len = boxes.length; i < len; i++){
			el = Ext.getCmp(boxes[i]);
			if (el.checked){
				checkedValues.push(el.value);
			}
		}
		
		var value = searchBox.getValue();
		
		var conn = new Ext.data.Connection();
		conn.request({
			url: portal_url + '/productlist/doCategorySearch',
			method: 'GET',
			params: {
				's': value,
				'levels': checkedValues
			},
			success: function(responseObject) {
				var jsonData = Ext.util.JSON.decode(responseObject.responseText);
				
				//highlight the categories that were returned
				var categoryGrid = Ext.getCmp('categoryCol').getView();
				
				//loop all rows first and clean out the highlight
				productTypeStore.each(function(rec){
					var dex = productTypeStore.indexOf(rec);
					var row = categoryGrid.getRow(dex);
					Ext.get(row).removeClass('grid-searchMatch');
					//Ext.get(row).setStyle( 'background-color', "ffffff");
				});
				
				for (i = 0, len = jsonData['Data'].length; i< len; i++){
					var cid = jsonData['Data'][i];
					
					//categoryGrid.getRow
					
				/*	var el = Ext.get(categoryGrid.getRow(cid));
					el.addClass('grid-searchMatch');
					*/
					var dex = productTypeStore.find('id',cid);
					var row = categoryGrid.getRow(dex);
					
					var el = Ext.get(row);
					el.addClass('grid-searchMatch');
					
					//apparently remove/addclass conflicts with highlight, remove it for now
					/*el.highlight("ffff9c", {
						attr: "background-color",
						easing: 'easeOut',
						duration: .5,
						endColor: "cbedf8"
					});*/
								
				}
				
			},
			 failure: function() {
				//if this doesn't work, life goes on
			 }
		});
	}
	
	
	
	function checkBoxHandler(cb, state){
		//no time to modify the Filterer object to accompany this type of data,
		//so do it this way...

		boxes = ['oesisok_identified_cb', 'oesisok_certified_cb', 'oesisok_gold_cb'];
		
		var checkedValues = [];
		for (var i=0, len = boxes.length; i < len; i++){
			el = Ext.getCmp(boxes[i]);
			if (el.checked){
				checkedValues.push(el.value);
			}
		}
		
		searchCategories();
		
		Filterer.delParam('Vendor_Id');
		Filterer.addParam('OKLevel', checkedValues, true);
		runFilters();
		
	}
	
	/************************************************************************
	 * EVENT ATTACHMENTS GO HERE
	 ************************************************************************/
	 
	 
	//events for updating the stores
    intermediaryStore.on('load', updateVendorsAndProducts);
	productTypeSelectionModel.on('rowselect', updateVendorColumn);
	productSelectionModel.on('rowselect', populateDetails);


	//when the vendor is selected...
	vendorSelectionModel.on('selectionchange', vendorSelect, this, {
		buffer: 150
	});

	searchBox.on('blur', function(field){
		newVal = field.getValue();
		
		var values = [];
		
		if (newVal != ''){
			values.push(newVal);
		}
		
		
		//wow this is retarded, we need to filter vendors that match the search
		//criteria first, then search products
		
		
		//filter vendors manually
		var uniqueVendors = []
		
		/*vendorStore.filter('name', newVal, true);
		uniqueVendors = vendorStore.collect('id', false, false);*/
		
		//search products
		Filterer.addParam('Product_Name', values);
		runFilters();
		
		//search categories
		searchCategories();
		
	});
	
    Ext.getCmp('oesisok_identified_cb').on('check', checkBoxHandler);
	Ext.getCmp('oesisok_certified_cb').on('check', checkBoxHandler);
	Ext.getCmp('oesisok_gold_cb').on('check', checkBoxHandler);
	
	//buttons
	Ext.get('resetBtn').on('click', function(evt, elem, obj){
		boxes = ['oesisok_identified_cb', 'oesisok_certified_cb', 'oesisok_gold_cb'];
		
		for (var i=0, len = boxes.length; i < len; i++){
			el = Ext.getCmp(boxes[i]);
			el.suspendEvents();
			el.reset();
			el.resumeEvents();
		}
		searchBox.suspendEvents();
		searchBox.reset();
		searchBox.resumeEvents();
		
		Filterer.reset();
		productStore.clearFilter();
		vendorStore.clearFilter();
		
	});
	
	
	/******* END EVENTS ******************************************************/
	
	/**************************************************************************
	 * Begin Panel Construction
	 **************************************************************************/
	
    var panel = new Ext.Panel({
        width: 940,
        height: 500,
		layout: 'border',
		renderTo: 'panel-area',
		baseCls : 'panelArea',
		//border: false,
		items: [{
			region: 'south',
			id: 'productDetails',
			xtype: 'productdetail',
			layout: 'fit',
			baseCls: 'detailsPanel',
			height: 225,
			title: 'Details',
			border: false,
			autoScroll: true
		},{
			border: false,
			layout: 'column',
			region: 'center',
			items: [{
				/**
				 * COLUMN 1
				 **/
				columnWidth: .25,
				id         : 'categoryCol',
				height     : 275,
				xtype      : 'grid',
				baseCls    : 'grid_col1',
				enableColumnResize : false,
				enableColumnMove: false,
				columns    : [
					{header: "Product Type", dataIndex: 'name', sortable: false}
				],
				sm         : productTypeSelectionModel,
				store      : productTypeStore,
				
				// force the grid to fit the space which is available
				viewConfig : {
					forceFit: true
				}
			},{
				/**
				 * COLUMN 2
				 **/
				columnWidth: .30,
				height: 275,
				id: 'vendorCol',
				baseCls    : 'grid_col2',
				xtype: 'grid',
				enableColumnResize : false,
				enableColumnMove: false,
                id: 'col2',
				columns: [
					{header: "Vendor", dataIndex: 'name', sortable: true}
				],
				sm: vendorSelectionModel,
				store: vendorStore,
				viewConfig: {
					forceFit: true,
					emptyText: 'No Vendors match your specified search criteria.'
				}
			},{
				/**
				 * COLUMN 3
				 **/
				columnWidth: .449,
				baseCls    : 'grid_col3',
				height: 275,
				id: 'productCol',
				xtype: 'grid',
				enableColumnResize : false,
				enableColumnMove: false,
				columns: [
					{header: "Product Name", dataIndex: 'Product_Name', sortable: true, renderer: productRenderer}
				],
				sm: productSelectionModel, 
				store: productStore,
				// force the grid to fit the space which is available
				viewConfig: {
					forceFit: true,
					emptyText: 'No Products match your specified search criteria.'
				}
			}]
		}]
    })	
});