/* Copyright 2009 Palm, Inc.  All rights reserved. */

var MoreAssistant = Class.create({
    initialize: function(params){
	    this.params = params || {};
		this.allApps = $A();
		this.aboutToActivateCallback = undefined;
		this.delayActivation = true; 
    },
	
	
    setup: function(){
		
		this.naiField = this.controller.get('nai-field');
		this.naiView = this.controller.get('naiView');
		this.installedAppView = this.controller.get("installedApps");
		this.palmAppView = this.controller.get("palmApps");
		this.softwareView = this.controller.get('softwareView');
		this.hardwareView = this.controller.get('hardwareView');
		this.installedAppView.hide();
		this.palmAppView.hide();
		
		this.COMMAND_MENU = {
	      loadSoftwareView: {command:'cmdLoadSoftware',target: this.loadSoftwareView.bind(this)},
	      loadHardwareView: {command:'cmdLoadHardware',target: this.loadHardwareView.bind(this)},
		  loadQuickTest: {command:'cmdQuickTest',target: this.loadQuickTest.bind(this)},
		  loadInteractiveTest: {command:'cmdInteractiveTest',target: this.loadInteractiveTest.bind(this)},
		  loadCertMgr: {command:'cmdCertMgr',target: this.loadCertMgr.bind(this)},
	    };                         

		Mojo.Log.info("setup ", Object.toJSON(this.params));
		if (this.params.manageApps == true) {
			this.toggleCmd = this.COMMAND_MENU.loadSoftwareView.command;
			this.currentView = softwareView;
			this.hardwareView.style.display = 'none';
		} else {
			this.toggleCmd = this.COMMAND_MENU.loadHardwareView.command;
			this.currentView = hardwareView;
			this.softwareView.style.display = 'none';
		}
	    
	    // Specifying the width in pixels is a hack.  The widget should support percentages.
	    this.topMenuModelItems = [
	        {label:'software / hardware', toggleCmd:this.toggleCmd, items:[
	          {label:$L('Software'), command:this.COMMAND_MENU.loadSoftwareView.command, width:160},
	          {label:$L('Hardware'), command:this.COMMAND_MENU.loadHardwareView.command, width:160}
	        ]}
	      ];         

		// Setup the top (view) menu
		this.topMenuModel = {
			visible: true,
			items: this.topMenuModelItems
		}; 
	    this.controller.setupWidget(Mojo.Menu.viewMenu, undefined, this.topMenuModel);

		var quickTestItem = {label:$L('Quick Tests...'), command:this.COMMAND_MENU.loadQuickTest.command, checkEnabled:true};
		var interactiveTestItem = {label:$L('Interactive Tests...'), command:this.COMMAND_MENU.loadInteractiveTest.command, checkEnabled:true};
		var certMgrItem = {label:$L('Certificate Manager...'), command:this.COMMAND_MENU.loadCertMgr.command, checkEnabled:true};

		var appMenuModel = {
            visible: true,
            items: [Mojo.Menu.editItem, quickTestItem, interactiveTestItem, certMgrItem, Mojo.Menu.helpItem]
        };
		
        this.controller.setupWidget(Mojo.Menu.appMenu, {omitDefaultItems: true}, appMenuModel);		

        // Default values for fields should be set here.
        this.fields = {
        };
		
		this.palmAppModel = {
            items: [],
			"listTitle": $L("Built-in applications")
        };
		
		this.otherAppModel = {
            items: [],
			"listTitle": $L("Downloaded applications")
        };

        this.phoneModel = {
            items: [],
			"listTitle": $L("Phone")
        };
        this.networkModel = {
            items: [],
			"listTitle": $L("Network")
        };
		
        this.palmApplicationListWidget = this.controller.get('palmApplicationList');
		this.controller.setupWidget('palmApplicationList', {
            itemTemplate: 'more/palmapp-item',
			listTemplate: 'more/listcontainer'
        }, this.palmAppModel);
		Mojo.Event.listen(this.palmApplicationListWidget, Mojo.Event.listTap, this.otherSelectionHandler.bind(this));
		
		this.otherApplicationListWidget = this.controller.get('otherApplicationList');
        this.controller.setupWidget('otherApplicationList', {
            itemTemplate: 'more/otherapp-item',
			listTemplate: 'more/listcontainer'
        }, this.otherAppModel);
		Mojo.Event.listen(this.otherApplicationListWidget, Mojo.Event.listTap, this.otherSelectionHandler.bind(this));

        this.controller.setupWidget('phoneList', {
            itemTemplate: 'list/item',
			listTemplate: 'list/listcontainer'
        }, this.phoneModel);
        this.controller.setupWidget('networkList', {
            itemTemplate: 'list/item',
			listTemplate: 'list/listcontainer'
        }, this.networkModel);
        // This initializes any default values in this.fields
		this.updateFields(this.palmAppItems, this.palmAppModel);
		this.updateFields(this.otherAppItems, this.otherAppModel);
		
        this.updateFields(this.phoneItems, this.phoneModel);
        this.updateFields(this.networkItems, this.networkModel);
        
        this.btprofilelistrequest = AppAssistant.btService.getProfileList(this.btProfileListCb.bind(this), this.controller);
        var props = [{
            key: "com.palm.properties.WIFIoADDR"
        }, {
            key: "com.palm.properties.BToADDR"
        }, {
            key: "com.palm.properties.PRODoID"
        }, {
            key: "com.palm.properties.DMCARRIER"
        },{
						key: "com.palm.properties.HWoRev"
				}];
		
        // Make service requests to get information.
        this.propertyGet = [];
		$A(props).each(function(a, index){
		 	this.propertyGet[index] = AppAssistant.propertiesService.get(a, this.takeProperties.bind(this), this.controller);
        }.bind(this));
		
        this.firmwareQuery = AppAssistant.telephonyService.firmwareQuery(this.takeValue.bind(this, "firmware"), this.controller);
        this.naiQuery = AppAssistant.telephonyService.pdpSlotQuery(this.takeSlot.bind(this), this.controller);
		this.prlversionQuery = AppAssistant.telephonyService.prlversionQuery(this.takeValue.bind(this, "prl"), this.controller);	

		this.imeiQuery = AppAssistant.telephonyService.imeiQuery(this.takeValue.bind(this, "imei"), this.controller);
        this.meidQuery = AppAssistant.telephonyService.meidQuery(this.takeValue.bind(this, "meid"), this.controller);
        this.iccidQuery = AppAssistant.telephonyService.iccidQuery(this.takeValue.bind(this, "iccid"), this.controller);
        this.esnQuery = AppAssistant.telephonyService.msidQuery(this.takeMsid.bind(this, "msid"), this.controller);
//        this.esnQuery = AppAssistant.telephonyService.esnQuery(this.takeValue.bind(this, "esn"), this.controller);
		
		this.btPanChange = AppAssistant.telephonyService.getBtPanRouteStatus(this.btPanChangeCallback.bind(this), this.controller);
		
		this.appManagerQuery = AppAssistant.appManagerService.listLaunchPoints(this.takeApps.bind(this), this.controller);
		
		this._subscribeToAppChanges();
    },

	btPanChangeCallback: function(response) {
		Mojo.Log.info("btPanChangeCallback ", Object.toJSON(response));
		var route = this.btRouteUp;
		var path = this.networkPath;
		if ("isBtPanToInternetRouteUp" in response) {
			this.btRouteUp = response.isBtPanToInternetRouteUp;
		}
		
		if("networkPath" in response) {
			this.networkPath = response.networkPath;
		}
		
		if(this.networkPath != path || this.btRoutUp != route){
			this.naiQuery = AppAssistant.telephonyService.pdpSlotQuery(this.takeSlot.bind(this), this.controller);
		}
	},
	
	otherSelectionHandler: function(event) {
		var item = event.item;
		Mojo.Log.info("listSelectionHandler item: " + Object.toJSON(item));
		this.controller.showDialog({
			template: 'more/dialogs/app-info',
			assistant: new AppInfoAssistant(this, item),
			icon: item.icon,
			title: item.title,
			version: item.version,
			vendor: item.vendor,
			vendorUrl: item.vendorUrl
		});

	},
	
	handleCommand: function(event) {
    	// handle menu button command events
		if(event.type == Mojo.Event.command) {
      		// determine if we have a target function for this command
	      	var menu = $H(this.COMMAND_MENU);
		    	menu.keys().each(function(key) {
			        var menuCommand = menu.get(key);
			        if (menuCommand.command == event.command) {
			          menuCommand.target();
			          Event.stop(event);
			          throw $break;
			        }
		      	});
		
			if(event.command == Mojo.Menu.helpCmd) {
				var openParams = { target: 'http://help.palm.com/device_info/index.html' };
				this.controller.serviceRequest('palm://com.palm.applicationManager',
				        {method: 'open', parameters: {id: 'com.palm.app.help',
				         params: openParams}});
			}
		} else if (event.type == Mojo.Event.commandEnable && 
		         (event.command == Mojo.Menu.helpCmd)) {
			event.stopPropagation();
		}
	},  
	
	loadSoftwareView: function(updateToggle) {
		var transition = null;
		transition = this.controller.prepareTransition(Mojo.Transition.crossFade);
	    

		if(updateToggle && this.topMenuModelItems[0].toggleCmd != this.COMMAND_MENU.loadSoftwareView.command) {
		       this.topMenuModelItems[0].toggleCmd = this.COMMAND_MENU.loadSoftwareView.command;
		       this.controller.modelChanged(this.topMenuModel);      
		}  	

		if (!this.currentView || this.currentView != this.softwareView) {
			this.hardwareView.style.display = 'none';			
			this.softwareView.style.display = 'block';
			this.controller.sceneScroller.mojo.revealTop(0);
			this.currentView = this.softwareView;
			
		}
		
		transition.run();

	},
	
	loadHardwareView: function(updateToggle) {
		var transition = null;
		transition = this.controller.prepareTransition(Mojo.Transition.crossFade);
		
	    if(updateToggle && this.topMenuModelItems[0].toggleCmd != this.COMMAND_MENU.loadHardwareView.command) {
		       this.topMenuModelItems[0].toggleCmd = this.COMMAND_MENU.loadHardwareView.command;
		       this.controller.modelChanged(this.topMenuModel);      
	    }  	

		if (!this.currentView || this.currentView != this.hardwareView) {
			this.softwareView.style.display = 'none';			
			this.hardwareView.style.display = 'block';						
			this.controller.sceneScroller.mojo.revealTop(0);
			this.currentView = this.hardwareView;	
			
		}		
		transition.run();

	},
	
	loadQuickTest: function() {
		Mojo.Log.info("loadQuickTest");
		var args = {
			appId: "com.palm.app.crotest",
			name: "automatedtests"
		};
		this.controller.stageController.pushScene(args, {});	
	},
	
	loadInteractiveTest: function() {
		Mojo.Log.info("loadInteractiveTest");
		var args = {
			appId: "com.palm.app.crotest",
			name: "interactivetests"
		};
		this.controller.stageController.pushScene(args, {});	
		
	},
	
	loadCertMgr: function() {
		Mojo.Log.info("loadCertMgr");
		var args = {
			appId: "com.palm.app.certificate",
			name: "list"
		};
		this.controller.stageController.pushScene(args, {});	  
	},
	
	
	/* listen to changes made to applications (add/remove) */
	_subscribeToAppChanges: function() {
		this.appChangeRequest = this.controller.serviceRequest('palm://com.palm.applicationManager', {
			method: 'launchPointChanges',
			parameters: {'subscribe':true},
			onSuccess: this._onAppChanged.bind(this)
		});
	},
	
	insertItem: function(item, model, widget) {
		
		var inserted = false;
		$A(model.items).each(function(a, index) {
			var compare = this.sortFunction(a, item);
			Mojo.Log.info("insertItem ", item.title, a.title, compare);
						
			if (compare == 0) {
				if (a.id == item.id) {
					inserted = true;
					throw $break;
				} else {
					compare = 1;
				}
			} 
			
			if (compare == 1) {
				inserted = true;
				model.items.splice(index, 0, item);
				widget.mojo.noticeAddedItems(index, [item]);
				throw $break;
			}
		}.bind(this));
		
		if(inserted == false){
			model.items.push(item);
			widget.mojo.noticeAddedItems(model.items.length, [item]);
		}
		
	},
	
	/* handle application changes (add/remove) */
	_onAppChanged: function(app) {
		Mojo.Log.info("onAppChanged ", Object.toJSON(app));
		if (app.change === "added") {
			delete app.change; // besides the 'change' field, this is a full blown JSON app object
			if(app.removable == true){
				this.insertItem(app, this.otherAppModel, this.otherApplicationListWidget);
				if (this.otherAppModel.items.length > 0) {
					this.installedAppView.show();
				}
			} else {
				this.insertItem(app, this.palmAppModel, this.palmApplicationListWidget);
			}					 
		} 
		else if (app.change === "removed") {
			delete app.change;
			var remove = 0;

			var f = function(a, index){
				if (app.id == a.id) {
					remove = index;
					throw $break;
				}
			};
			
			if(app.removable == true){
				$A(this.otherAppModel.items).each(f);
				this.otherAppModel.items.splice(remove, 1);
				this.otherApplicationListWidget.mojo.noticeRemovedItems(remove, 1);
				if (this.otherAppModel.items.length == 0) {
					this.installedAppView.hide();
				}

			} else {
				$A(this.palmAppModel.items).each(f);
				this.palmAppModel.items.splice(remove, 1);
				this.palmApplicationListWidget.mojo.noticeRemovedItems(remove, 1);
			}
		}
		/*
		else if (app.change === "update") {
			delete app.change;
		}
		*/
	},
	
	sortFunction: function(a,b){
		var c = a.title.toLowerCase();
		var d = b.title.toLowerCase();
		return ((c < d) ? -1 : ((c > d) ? 1 : 0));
	},
	
	takeSlot: function(payload) {
		Mojo.Log.info("takeSlot " + Object.toJSON(payload));
        if (!payload) 
            return;
//        if (!("extended" in payload)) 
//            return;
        if (!("slot" in payload)) 
            return;
		var slot = payload.slot;	
		AppAssistant.telephonyService.pdpProfileQuery(slot, this.takeNai.bind(this, "nai"), this.controller);
	},
	
	takeNai: function(item, payload) {
		Mojo.Log.info("takeNai " + Object.toJSON(payload));
        if (!payload) 
            return;
        if (!("extended" in payload)) 
            return;
        if (!("nai" in payload.extended)) 
            return;
		this.naiView.show();	
		this.naiField.innerHTML = payload.extended.nai;
			
//        this.fields[item] = payload.extended.nai;
//        this.updateFields(this.networkItems, this.networkModel);

	},
	
	takeApps: function(payload) {
		Mojo.Log.info("takeApps ", Object.toJSON(payload));
		
//		this.allApps = payload.apps;
		this.allApps = payload.launchPoints;
		this.allApps.sort(this.sortFunction);
		
		$A(this.palmAppModel.items).clear();
		$A(this.otherAppModel.items).clear();
		
		this.allApps.each(function(item, index){
			Mojo.Log.info("takeApps " + Object.toJSON(item));
			
			if (item.removable == false) {				
				this.palmAppModel.items.push(item);
			} else {
				if (item.launchPointId.startsWith(item.id)) {
					this.otherAppModel.items.push(item);
				}
			}
		}.bind(this));
		
		this.controller.modelChanged(this.palmAppModel);
		this.controller.modelChanged(this.otherAppModel);
		
		if (this.otherAppModel.items.length > 0) {
			this.installedAppView.show();
		}
		
		this.palmAppView.show();	

	},

	takeMsid: function(item, payload){
		Mojo.Log.info("takeMsid " + Object.toJSON(payload));
        if (!payload) 
            return;
        if (!("extended" in payload)) 
            return;
        if (!("msid" in payload.extended)) 
            return;
        this.fields[item] = payload.extended.msid;
        this.updateFields(this.networkItems, this.networkModel);
    },
	
    takeValue: function(item, payload){
		Mojo.Log.info("takeValue ", item, Object.toJSON(payload));
        if (!payload) 
            return;
        if (!("extended" in payload)) 
            return;
        if (!("value" in payload.extended)) 
            return;
        this.fields[item] = payload.extended.value;
        this.updateFields(this.networkItems, this.networkModel);
		
		if(item == "firmware"){
			this.delayActivation = false;
			Mojo.Log.info("firmware found.");
			if(this.aboutToActivateCallback)
				this.aboutToActivateCallback();
		}
    },
    
    takeProperties: function(payload){
		Mojo.Log.info("takeProperties " + Object.toJSON(payload));
        if (!payload) 
            return;
        if ("com.palm.properties.WIFIoADDR" in payload) 
            this.fields.wifi = payload["com.palm.properties.WIFIoADDR"];
        if ("com.palm.properties.BToADDR" in payload) 
            this.fields.bt = payload["com.palm.properties.BToADDR"];
        if ("com.palm.properties.PRODoID" in payload) 
            this.fields.model = payload["com.palm.properties.PRODoID"];
        if ("com.palm.properties.DMCARRIER" in payload) 
            this.fields.network = payload["com.palm.properties.DMCARRIER"];
				if("com.palm.properties.HWoRev" in payload)
						this.fields.hardwareVersion = payload["com.palm.properties.HWoRev"];

        
        this.updateFields(this.phoneItems, this.phoneModel);
        this.updateFields(this.networkItems, this.networkModel);
    },
	
	  
    carrierDbResponse: function(item, payload){
        Mojo.Log.info(Object.toJSON(payload));
		if(!payload)
			return;
			
		if(!('apnLabel' in result))
			return;
			
        this.fields[item] = result.apnLabel;
		this.updateFields(this.networkItems, this.networkModel);
        
    },
    
    loadCarrierDbList: function(){
        var handle = this.controller.serviceRequest("palm://com.palm.data.carriernetworksettings", {
            method: 'getApn',
            parameters: {
                'apnType': "internet"
            },
            onSuccess: this.carrierDbResponse.bind(this, 'apn'),
			onFailure: function() {}
        });
    },

    
    updateFields: function(list, model){
        model.items = [];
        var index = 0;
        for (var i in list) {
            var item = list[i];
            if (item.field in this.fields) {
                model.items[index] = {
                    title: item.title,
                    data: this.fields[item.field]
                };
                if ("upper" in item) {
                    model.items[index].data = model.items[index].data.toUpperCase();
                }
                index++;
            }
        }
        this.controller.modelChanged(model, this);
    },
    
    btProfileListCb: function(payload){
        if (!payload.returnValue) 
            return;
        var profiles = payload.list.toString().toUpperCase().gsub(',', ', ');		
        this.controller.get('btprofiles').update($L("Supported Bluetooth profiles: ") +"<br>" + profiles);
    },
    
	aboutToActivate: function(callback) {
		Mojo.Log.info("more aboutToActivate");
		if (this.delayActivation)
			this.aboutToActivateCallback = callback;
		else
			callback();
			
	},

    activate: function(){	
		Mojo.Log.info("more activate");	
    },

    deactivate: function(){
		Mojo.Log.info("more deactivate");
    },
    
    cleanup: function(){
		Mojo.Log.info("more cleanup");
    },
    
    setSceneHeader: function(text){
        this.controller.get('prefheader').update(text);
    },
    
	palmAppItems: [],
	
	otherAppItems: [],
	
    networkItems: [{
        title: $L("Carrier"),
        field: "network"
    },  {
        title: $L("Firmware"),
        field: "firmware"
    }, {
        title: $L("IMEI"),
        field: "imei"
    }, {
        title: $L("MSID"),
        field: "msid",
        upper: true
    }, {
        title: $L("MEID"),
        field: "meid"
    }, {
        title: $L("NAI"),
        field: "nai"
    }, {
        title: $L("ICCID"),
        field: "iccid"
    }, {
        title: $L("PRL"),
        field: "prl"
    }],
    
    phoneItems: [{
        title: $L("Model"),
        field: "model"
    }, {
        title: $L("Wi-Fi"),
        field: "wifi"
    }, {
        title: $L("Bluetooth"),
        field: "bt"
    },{
        title: $L("Hardware Version"),
        field: "hardwareVersion"
    }],

});



