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

var label_title_update = $L('Palm webOS Update');
var label_title_failure = $L('Download Failed');

var label_button_continue = $L('Install now');
var label_button_ok = $L('OK');
var label_button_download = $L('Download now');

var label_progress_downloading = $L('Downloading...');
var label_progress_validating = $L('Validating...');
var label_progress_waitingForNetwork = $L('Waiting for the network...');
var label_progress_unpacking = $L('Unpacking...');

var label_downrev_title =  $L('Device downgrade');
var label_downrev_message = $L('Are you sure you want to install an older revision of the software.');
var label_downrev_continue = $L('Continue');
var label_downrev_cancel = $L('Cancel');

var updatesPath = "/usr/palm/applications/com.palm.app.updates";
var updatesResources = updatesPath + "/resources/";

var banner_catagory = "com.palm.app.updates";
		
		
	
var DetailAssistant = Class.create({
    initialize: function(params){
		console.log("Details: initialize params " + Object.toJSON(params));
		this.appAssistant = Mojo.Controller.getAppController().assistant;
        this.params = params || {};
		this.autoUpdate = this.params.autoUpdate || false;
		if(this.autoUpdate === true){
			this.firstUseUtils = FirstUseUtil.getUtil();
		}

        this.state = "";
        this.serviceRequest = null;
        this.downloadSubscription = null;
        this.validateSubscription = null;
        this.payload = {};
        this.initialized = false;
        this.installBegun = false;
        this.batteryPercent = 0;
		this.releaseNotes = undefined;
    },
    
    
    $L: function(str){
		if(this.stringTable == null){
			this.stringTable = Mojo.Locale.readStringTable("strings.json", Mojo.Locale.current, updatesResources);
		}
		return Mojo.Locale.localizeString(str, this.stringTable)
	},	
	
	setup: function(){
		Mojo.Log.info("Details:: setup");
		this.updateModel = UpdateModel.getModel();
		this.Depot = UpdatesDepot.getDepot();
		 
 		if(!this.releaseNotes && (this.autoUpdate === false)) {
			this.getReleaseNotes();
		}

		this.joinButtonModel = {buttonLabel: $L(label_button_ok)};
		this.joinButton = this.controller.get('doneButton');
        this.controller.setupWidget('doneButton', {}, this.joinButtonModel);
		Mojo.Event.listen(this.joinButton,'mojo-tap', this.systemClickCallback.bindAsEventListener(this))

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

        this.dProgressModel = {
            title: $L(label_button_download),
			icon: 'none'
        };
        this.dProgressAttr = {
            image: 'images/small.png'
        };        
        this.controller.setupWidget('downloadProgress', this.dProgressAttr, this.dProgressModel);		
		Mojo.Event.listen(this.controller.get('downloadProgress'), Mojo.Event.tap, this.systemClickCallback.bindAsEventListener(this));
		Mojo.Event.listen(this.controller.get('downloadProgress'), Mojo.Event.progressIconTap, this.progressCancelled.bindAsEventListener(this));

		Mojo.Event.listen(this.controller.document, Mojo.Event.deactivate, this.onBlur.bind(this), false);
		Mojo.Event.listen(this.controller.document, Mojo.Event.activate, this.onFocus.bind(this), false);

		var spinnerAttrs = {
			spinnerSize: Mojo.Widget.spinnerLarge
		};
		this.installingSpinner = this.controller.get("installing-spinner");
		this.controller.setupWidget('installing-spinner', spinnerAttrs, {});
        
		this.controller.get('scrim').hide();
		
		this.validationRequest = this.controller.serviceRequest('palm://com.palm.bus/signal', {
            method: 'registerServerStatus',
            parameters: {
                'serviceName': 'com.palm.validation',
				subscribe:true
            },
            onSuccess: this.subscribeValidationCallback.bind(this),
            onFailure: function(){
                Mojo.Log.info("failed to subscribe for bus signal");
            }
        });
		
		
		if (this.autoUpdate === true) {
			Mojo.Log.info("Details: Show emergency");
			this.controller.document.body.className = "firstuse palm-dark";
			Mojo.Event.listen(this.controller.get('firstuse_emergency'), Mojo.Event.tap, this.onEmergencyTap.bind(this));
			this.keyPressEventHandler =  this.firstUseUtils.handleKeyPressEvent;
			this.controller.listen(this.controller.sceneElement, Mojo.Event.keydown, this.keyPressEventHandler);
		}

    },
	
	getReleaseNotes: function(){
		this.Depot.getNextReleaseDetails(function(html){
				Mojo.Log.info("Details: next notes", html);
				this.releaseNotes = html;
				if ((this.state == "Available") || (this.state == "InstallBegun") || (this.state == "Countdown")) {
					this.controller.get('info_install').style.display = "none";
					this.controller.get('info_install_notes').style.display = "block";
					this.controller.get('info_version_install_notes').update(this.payload.version);
				}
				
				this.controller.get('release_notes_download').innerHTML = html;
				this.controller.get('release_notes_downloading').innerHTML = html;
				this.controller.get('release_notes_install').innerHTML = html;										
			}.bind(this)
		);
		this.Depot.getNewReleaseDetails(function(html){Mojo.Log.info("Details: new notes", html);}.bind(this));
	},

	onEmergencyTap: function() {
		var labels = [];
		if(this.firstUseUtils.customerCareNumber && this.firstUseUtils.customerCareNumber.length > 0) {
			labels = [{label: $L('Emergency call'), command: 'emergency-call'}, 
					{label: $L('Call customer service'), command: 'customer-care'},
					{label: $L('Cancel'), command: 'cancel'}
			];
		} else {
			labels = [{label: $L('Emergency call'), command: 'emergency-call'},
					{label: $L('Cancel'), command: 'cancel'}
			];
		}

		this.controller.popupSubmenu({
	   		onChoose: function(value) {
				if ( "emergency-call" === value ) {
					this.emergencyDial();
				} else if ("customer-care" === value){
					this.customerCareDial();
				}
			}.bind(this),
	   		placeNear: this.controller.get('firstuse_emergency_menu_anchor'),			
			items: labels
		});
	},

	emergencyDial: function(number) {
		if ( ! number ) {
			number = this.firstUseUtils.emergencyNumbers.first();
		}
		this.firstUseUtils.makeEmergencyCall(number);
	},
	
	customerCareDial: function(number) {
		if ( ! number ) {
			number = this.firstUseUtils.customerCareNumber;
		}
		this.firstUseUtils.callCustomerCare(number);
	},

	callback: function(payload){
		Mojo.Log.info("Details: callback " + Object.toJSON(payload));
		
		if (("version" in payload) && (this.autoUpdate === true) && (this.initialized == false)) {
			Mojo.Log.info("testing testing");
			this.Depot.setNextVersion(payload.version);
			this.getReleaseNotes();					
		}			

        if (!("status" in payload)) {
			Mojo.Log.info("Details: getStatus callback return");
            return;
        }

        if (this.initialized == false) {
            this.controller.get('progressCaption').innerHTML = $L(label_title_update);
            this.initialized = true;
        }

		this.updatePayload(payload);
    },
	
	updatePayload: function(payload){
		this.payload = payload;
		this.updateState();
	},
    
	cancelSuccess: function(payload){
		this.cancelDownload = false;
	},

	downloadSuccess: function(payload){

	},
	
    dummy: function(event){
    },
    
    systemClickCallback: function(event){
		Mojo.Log.info("Details: systemClickCallback");
		if(this.dProgressModel.disabled == true)
			return;

		if(this.cancelDownload == true)			
			return;

        if ((this.state == 'Waiting') || (this.state == 'NetworkFailed') || (this.state == 'DownloadRetry')) {
			console.log("Details: waiting " + this.state);
			this.updateModel.downloadNow(this.downloadSuccess.bind(this));
			if (!this.autoUpdate === true) {
				this.dProgressModel.icon = "action-icon";
			}			
			this.controller.modelChanged(this.dProgressModel);
        }
        else if (this.state == 'Available' || this.state == 'Countdown') {
            if (this.downRev) {
                this.controller.showAlertDialog({
                    onChoose: function(value){
                        if (value == 'continue') 
                            this.startInstall();
                    }.bind(this),
                    title: $L(label_downrev_title),
                    message: $L(label_downrev_message),
                    choices: [{
                        label: $L(label_downrev_continue),
                        value: "continue",
                        type: 'negative'
                    }, {
                        label: $L(label_downrev_cancel),
                        value: "cancel",
                        type: 'dismiss'
                    }, ]
                });
            }
            else {
                this.startInstall();
            }
        } else if (this.state == "SpaceNeeded") {
			window.close();
		} else if (this.state == "InvalidUpdate") {
			var sceneArgs = { name: 'main', transition: Mojo.Transition.crossFade };
			if (this.autoUpdate === true) {
				this.params.checkForUpdate = true;
				Mojo.Controller.stageController.swapScene(sceneArgs, this.params);				
			} else {				
				Mojo.Controller.stageController.swapScene(sceneArgs, { checkForUpdate: false });
			}
		}
    },
    
	progressCancelled: function(){
		Mojo.Log.info("Details: progressCancelled");
		if (this.state != "Downloading" || this.autoUpdate === true) {
			this.systemClickCallback();
			return;
		}

		this.cancelDownload = true;
		this.updateModel.cancelDownload(this.cancelSuccess.bind(this));
		this.dProgressModel.icon = "none";
		this.controller.modelChanged(this.dProgressModel);
	},

    // Called after "install pending" token has been written.
    // Starts actual install process.
    startInstall: function(){
		console.log("Details: startInstall");
		this.installBegun = true;
		this.controller.get('scrim').show();
		this.installingSpinner.mojo.start();
		this.updateModel.installNow(null);
		this.updateState();
    },
    
    progressCallback: function(payload){
		console.log("progressCallback " + Object.toJSON(payload) + " " + this.state);
        if ("percent" in payload) {
			if (this.state == 'Validating') {
				this.dProgressModel.value = payload.percent / 100.0;
				this.controller.modelChanged(this.dProgressModel);
            }
        }
    },
    
    progressFailCallback: function(payload){
		console.log("Details: progressFail " + Object.toJSON(payload));
    },
    
    updateState: function(){
		Mojo.Log.info("Details: updateState ", Object.toJSON(this.payload), this.state);
        var infoString = "";
		
		var sceneArgs = {name:'main', transition:Mojo.Transition.crossFade };
        if(this.state == "InvalidUpdate" && this.payload.status == "UpToDate") {
			return;	
		} else if ((this.payload.status == 'UpToDate') || (this.payload.status == 'Checking')) {
			if(this.autoUpdate === true){
				this.params.checkForUpdate = true;
				Mojo.Controller.stageController.swapScene(sceneArgs, this.params);
			} else {
				Mojo.Controller.stageController.swapScene(sceneArgs);
			}
            return;
        }  else if (this.payload.status == 'CancelAlert') {
            return;
        }
        
        // Find error conditions.
        this.oldState = this.state;
        this.state = this.payload.status;
		
		if(this.payload.downRev)
			this.downRev = this.payload.downRev;
		else 
			this.downRev = false;
		
        if (this.installBegun) 
            this.state = 'InstallBegun';
			
        if ("spaceNeeded" in this.payload) {
            if (this.payload.spaceNeeded > 0) 
                this.state = 'SpaceNeeded';
        }
		
		var highSpeedNeeded = false;
		if ("lowSpeed" in this.payload) {
			highSpeedNeeded = this.payload.lowSpeed;
		}
		
		var roaming = false;
		if ("roaming" in this.payload) {
			roaming = this.payload.roaming;
		}

		var carrier = "";
		if ("carrier" in this.payload) {
			carrier = this.payload.carrier;
		}
		
        // Fill bottom button with correct info.
        var networkAvailable = true;
        if ("networkAvailable" in this.payload) {
			networkAvailable = this.payload.networkAvailable;
		}        
		
		Mojo.Log.info("Details: updateState " + this.state);
		this.controller.get('doneButton').style.visibility = "hidden";
		this.controller.get('downloadProgress').style.visibility = "visible";
		
		// update the button
        if ((this.state == "Downloading") || (this.state == "Validating")) {
			this.dProgressModel.disabled = false;
			this.controller.modelChanged(this.dProgressModel);
        } else if ( (this.state == "Waiting") || (this.state == "Download2G") || (this.state == "DownloadRetry") ) {

			this.dProgressModel.value = undefined;
			this.dProgressModel.icon = "none";
			this.controller.modelChanged(this.dProgressModel);

			if ((networkAvailable == false) || (roaming == true)) {
				this.dProgressModel.disabled = true;
				this.dProgressModel.title = $L(label_progress_waitingForNetwork);
				this.controller.modelChanged(this.dProgressModel);

			} else {
				this.dProgressModel.disabled = false;
				this.dProgressModel.title = $L(label_button_download);
				this.controller.modelChanged(this.dProgressModel);
				
				if (this.autoUpdate === true) {					
					this.systemClickCallback();
					return;
				}
			}
			
        } else if ((this.state == "Available") || (this.state == "Countdown")) {			
			this.dProgressModel.value = undefined;
			this.dProgressModel.icon = "none";
			this.dProgressModel.title = $L(label_button_continue);
			this.dProgressModel.disabled = false;
			this.controller.modelChanged(this.dProgressModel);
			
        } else if (this.state == "InstallBegun") {

        } else if (this.state == "SpaceNeeded") {
			this.dProgressModel.value = undefined;
			this.dProgressModel.title = $L(label_button_ok);
			this.dProgressModel.disabled = false;
			this.controller.modelChanged(this.dProgressModel);
			this.controller.get('doneButton').style.visibility = "visible";
			this.controller.get('downloadProgress').style.visibility = "hidden";

        } else if (this.state == "InvalidUpdate") {
			this.dProgressModel.value = undefined;
			this.dProgressModel.title = $L(label_button_ok);
			this.controller.modelChanged(this.dProgressModel);
			this.dProgressModel.disabled = false;
			this.controller.get('progressCaption').innerHTML = $L(label_title_failure);			
			this.controller.get('doneButton').style.visibility = "visible";
			this.controller.get('downloadProgress').style.visibility = "hidden";
			
		} else if (this.state == "InsufficientCharge") {
			this.dProgressModel.value = undefined;
			this.dProgressModel.title = $L(label_button_continue);			
			this.dProgressModel.icon = "none";
			this.dProgressModel.disabled = true;
			this.controller.modelChanged(this.dProgressModel);
			this.controller.get('downloadProgress').style.visibility = "hidden";

        } else if (this.state == 'NetworkFailed') {
			this.dProgressModel.value = undefined;
			this.dProgressModel.title = $L(label_button_download);
			this.dProgressModel.icon = "none";
			this.dProgressModel.disabled = false;
			this.controller.modelChanged(this.dProgressModel);
			
		} else {
            Mojo.Log.info('Details: unknown state: ' + this.state);
        }
        
        // Update progress pill for relevant states.
        if (this.state == "Downloading") {

			if ("percent" in this.payload)
				this.dProgressModel.value = this.payload.percent / 100.0;
			else
				this.dProgressModel.value = 0;

			if (networkAvailable == false) {
				this.dProgressModel.title = $L(label_progress_waitingForNetwork);
			} else {
				this.dProgressModel.title = (this.dProgressModel.value >= 0.45) ? $L(label_progress_unpacking) : $L(label_progress_downloading);
			}

			if (!this.autoUpdate === true) {
				this.dProgressModel.icon = "action-icon";
			}
			Mojo.Log.info('Details: update progress model: ' + this.dProgressModel.value);
			this.controller.modelChanged(this.dProgressModel);
        }
        else if (this.state == "Validating") {
			this.dProgressModel.value = 0;
			this.dProgressModel.icon = "none";
			this.dProgressModel.title = $L(label_progress_validating);
			this.controller.modelChanged(this.dProgressModel);
        } else {
        }
        
		// update the text
		this.controller.get('info_roaming').style.display = "none";
		this.controller.get('info_nonetwork').style.display = "none";
		this.controller.get('info_highspeed').style.display = "none";
		this.controller.get('info_nohighspeed').style.display = "none";
		this.controller.get('info_nohighspeedblockedvoice').style.display = "none";
		
		this.controller.get('info_failure').style.display = "none";
		this.controller.get('info_failure_firstuse').style.display = "none";
		this.controller.get('info_download').style.display = "none";
		this.controller.get('info_downloading_notify').style.display = "block";
		this.controller.get('info_downloading').style.display = "none";
		this.controller.get('info_install').style.display = "none";
		this.controller.get('info_install_notes').style.display = "none";
		this.controller.get('info_freeSpace').style.display = "none";
		this.controller.get('info_battery').style.display = "none";
		this.controller.get('info_failedconnection').style.display = "none";
		
        if ((this.state == "Waiting") || (this.state == 'NetworkFailed') || 
        	(this.state == "Download2G") ||	(this.state == "DownloadRetry") ) {
            this.controller.get('info_download').style.display = "block";
			this.controller.get('info_size').update(this.payload.size);
			this.controller.get('info_version').update(this.payload.version);
		} else if ((this.state == "Downloading") || (this.state == "Validating")) {			
			this.controller.get('info_downloading').style.display = "block";
			this.controller.get('info_version_downloading').update(this.payload.version);
        } else if ((this.state == "Available") || (this.state == "InstallBegun") ||
					(this.state == "Countdown")) {
			if (this.releaseNotes) {
				this.controller.get('info_install_notes').style.display = "block";
				this.controller.get('info_version_install_notes').update(this.payload.version);
			} else {
				this.controller.get('info_install').style.display = "block";
				this.controller.get('info_version_install').update(this.payload.version);
			}
        } else if (this.state == "SpaceNeeded") {
            this.controller.get('info_freeSpace').style.display = "block";
			this.controller.get('info_spaceNeeded').update(this.payload.spaceNeeded);
		} else if (this.state == "InsufficientCharge") {
			this.controller.get('info_battery').style.display = "block";
        } else {
            Mojo.Log.info('Details: text unknown state: ' + this.state);
        }
		
		if (this.state == 'NetworkFailed') {
			this.controller.get('info_failedconnection').style.display = "block";
		}
		
		if (this.state == "InvalidUpdate") {			
			if(this.autoUpdate === true){
				this.controller.get('info_failure_firstuse').style.display = "block";
			} else {
				this.controller.get('info_failure').style.display = "block";	
			}
		}
		
		if (networkAvailable == false) {
			this.controller.get('info_nonetwork').style.display = "block";
		} else if (roaming == true) {
			this.controller.get('info_roaming').style.display = "block";	
		} else if (highSpeedNeeded == false) {
			this.controller.get('info_highspeed').style.display = "block";			
		} else if(AppAssistant.dataBlocksCalls) {
			this.controller.get('info_nohighspeedblockedvoice').style.display = "block";
		} else {	
			this.controller.get('info_nohighspeed').style.display = "block";
		}
    },

	subscribeValidationCallback: function(result){
        Mojo.Log.info("Details: Mojo Service Validate state " + result.connected);
        if (result.connected == true) {
            // Subscribe to network status
            this.validateSubscription = AppAssistant.validationService.progress(this.progressCallback.bind(this), this.progressFailCallback.bind(this), this.controller);
        }
        else {
			if(this.validateSubscription)
				this.validateSubscription.cancel();
        }
    },
	
	handleCommand: function(event) {
		if(event.type == Mojo.Event.command) {
			if (event.command == Mojo.Menu.helpCmd) {
				Event.stop(event);
				var openParams = {					
					target: 'http://help.palm.com/updates/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();
		}
	},
		
		
	onBlur: function(event) {
		Mojo.Log.info("Details: BLUR ");
		this.appFocus = false;
	},
	
	onFocus: function(event) {
		Mojo.Log.info("Details: FOCUS ");		
		this.appFocus = true;
	},
	
    activate: function(){
		this.updateModel.setCallback(this.callback.bind(this));
		if(this.autoUpdate === true) {
			this.timer = setTimeout(this.activateScene.bind(this), 2000);
		}
    },
	
	activateScene: function () {
		Mojo.Controller.stageController.activate();
	},
	
    deactivate: function(){
		Mojo.Log.info("Details: DEACTIVATE ");
    },

    cleanup: function(){
		Mojo.Log.info("Details: CLEANUP ");
		
        if (this.cancelRequest != null) 
            this.cancelRequest.cancel();
        if (this.downloadRequest != null) 
            this.downloadRequest.cancel();
        if (this.serviceRequest != null) 
            this.serviceRequest.cancel();
        if (this.downloadSubscription != null) 
            this.downloadSubscription.cancel();
        if (this.validateSubscription != null) 
            this.validateSubscription.cancel();
        if (this.powerNotificationSession != null) 
            this.powerNotificationSession.cancel();
        detailCallback = null;				
    },
	
    setSceneHeader: function(text){
        $('prefheader').update(text);
    },

});
