/* Copyright 2009 Palm, Inc.  All rights reserved. */
/*global Mojo, Class, $L, Template, WordAssistant, ExcelAssistant, PowerPointAssistant,
 PropertiesDialogAssistant:true, OptionsDialogAssistant:true, SaveAsDialogAssistant:true */
/*jslint rhino:true, undef:true */

var DocumentAssistant = Class.create({

	appMenuModel: { visible:true, label:$L('PDF View'), omitDefaultItems:true,
        items: [
        { label:$L('Open'), command:'file-open-cmd' },
        { label:$L('Save As...'), command:'file-saveas-cmd' },
        { label:$L('Share'), command:'share-cmd' },
        { label:$L('Find'), command:'find-cmd', chosen:false },
        { label:$L('Bookmarks'), command:'pdf-outline', chosen:false },
        { label:$L('Help'), command:Mojo.Menu.helpCmd, checkEnabled:true }
    ]},

	cmdMenuModel: { visible: false, items: [
		{},
		{ items: [
			{ icon:'back', command:'prev-cmd' },
			{ template: 'document/command_bar', command: 'edit-cmd' },
			{ icon:'forward', command:'next-cmd' }
		]},
		{}
	]},

	numericMap: {
		e:'1',r:'2',t:'3',
		d:'4',f:'5',g:'6',
		x:'7',c:'8',v:'9',
			'@':'0',

		1:'1',2:'2',3:'3',
		4:'4',5:'5',6:'6',
		7:'7',8:'8',9:'9',
			  0:'0'
	},

    activate: function() {
        this.findField.mojo.focus();
    },

    deactivate: function() {
        this.findField.mojo.blur();
    },

	initialize: function(parameters) {

		this.pagecount = 0;
		this.errorText = undefined;
		this.document_noext = undefined;
		this.saveShowing = false;
		this.currentpage = 1;
		this.wrongpasscount = -1;
		this.jumptimeout = undefined;
		this.outline_depth = 1;
		this.cur_depth = 1;
		this.outline_lastcnt = 0;
		this.lastcount = 0;
		this.pageFootFirst = true;
		this.pageFootEdit = false;
		this.lastpage = 1;
		this.resultCount = undefined;
		this.document_name = undefined;
		this.document_id = undefined;
		this.adapter = undefined;
		this.filename = undefined;
		this._loadingSpinner = null;
		this._loadingSpinnerTimeout = null;
		this._spinnerShowTime = 0;
        this.documentPassword = null;

        // Variables need for find / search
        this.findShowing = false;
        this.findString = '';
        this.newFindString = '';
        this.findCancel = false;
		this.showFootPageOf = this.showFootPageOf.bind(this);
		this.handleFootPage = this.handleFootPage.bind(this);
		this._handleFocus = this._handleFocus.bind(this);
		this._showLoadingSpinner = this._showLoadingSpinner.bind(this);
		this._hideLoadingSpinner = this._hideLoadingSpinner.bind(this);
		this.gestureEndCallAdapter = this.gestureEndCallAdapter.bind(this);
		this.executeJump = this.executeJump.bind(this);
        this.ChangePagesBy = this.ChangePagesBy.bind(this);

        this.filename = undefined;
        if (parameters.launchParams && parameters.launchParams.target) {
            this.filename = parameters.launchParams.target;
        }
        else if (parameters.filename) {
            this.filename = parameters.filename;
        }

        if (this.filename && this.filename.startsWith('file://')) {
            this.filename = this.filename.substr(7);
        }

        Mojo.Log.info("Filename = '%s'", this.filename);
    },

    setup: function() {
        Mojo.Log.info("DocumentAssistant: setup filename('%s')", this.filename);

        try {

            this.spinnerRunning = false;

			// Set up the view buttons (header)
			var viewMenuModel = { visible: false, items: [ { template: 'document/header_bar' } ] };
            this.controller.setupWidget(Mojo.Menu.viewMenu,
                                        {menuClass:'no-fade'},
                                        viewMenuModel);

			// Set up the command buttons (footer)
            this.controller.setupWidget(Mojo.Menu.commandMenu,
                                        {menuClass:'no-fade'},
                                        this.cmdMenuModel);

            this.controller.get('PlugIn').observe(Mojo.Event.flick,
                                this.flickcheck.bindAsEventListener(this));

            this.controller.get('PlugIn').observe(Mojo.Event.tap,
                                this._onTap.bindAsEventListener(this));

            this.controller.get('PlugIn').observe('mousedown',
                                this.mousecheck.bindAsEventListener(this));

            this.controller.document.addEventListener('gesturestart',
                    this.gestureStart.bindAsEventListener(this), true);

            this.controller.document.addEventListener('gesturechange',
                    this.gestureChange.bindAsEventListener(this), true);

            this.controller.document.addEventListener('gestureend',
                    this.gestureEnd.bindAsEventListener(this), true);

            this.dosetup.bind(this).defer();

            var appAttrs = {
				omitDefaultItems: true
			};
            this.controller.setupWidget(Mojo.Menu.appMenu, appAttrs, this.appMenuModel);

            // Setup Find Widget
            var findAttributes = {
				enableNxtPrv: true,
				findFieldName: 'find_it',
				handleClear: true,
				handleEnter: true,
				showOnKey: true,
				widgetTop: '0px'
			};
            this.controller.setupWidget('findField', findAttributes, undefined);

            // Setup Spinner Widget
            var spinnerAttributes = {
				property: 'p',
				spinnerSize: 'small'
			};
            this.spinnerModel = {
				p: false
			};
            this.controller.setupWidget('my_spinner',
                                        spinnerAttributes,
                                        this.spinnerModel);

            // This is the widget for the Save As scene
            var saveAttributes = {
				modelProperty: 'original',
				autoResize: false,
				multiline: false,
				enterSubmits: false,
				limitResize: false,
				disabledProperty: 'p',
				focusMode: Mojo.Widget.focusSelectMode
			};
            this.saveModel = {
				p: false,
				'original': ''
			};
            this.controller.setupWidget('text_field',
                                        saveAttributes,
                                        this.saveModel);

            // Handle Events
            this.findField = this.controller.get('findField');

            this.findField.addEventListener('mojo-find-clear',
                    this.handleFindClear.bindAsEventListener(this));

            this.findField.addEventListener('mojo-find-go',
                    this.handleFindGo.bindAsEventListener(this));

            this.findField.addEventListener('mojo-find-prev',
                    this.handleFindPrev.bindAsEventListener(this));

            this.findField.addEventListener('mojo-find-next',
                    this.handleFindNext.bindAsEventListener(this));

            this.controller.document.addEventListener(Mojo.Event.activate,
                    this._handleFocus, false);

            this.controller.document.addEventListener(Mojo.Event.deactivate,
                    this._handleFocus, false);

            if (findAttributes.showOnKey) {
                this.controller.listen( this.controller.sceneElement, Mojo.Event.keydown,
                        this.handleKeyDown.bindAsEventListener(this) );
            }

			this.controller.setupWidget('loading-doc-spinner', {spinnerSize:Mojo.Widget.spinnerLarge});
			this._loadingSpinner = this.controller.get('loading-doc-spinner');
        }
        catch (e) {
            Mojo.Log.logException(e, 'setup');
        }
    },

    orientationChanged: function(orientation) {

       return;
/*
       if (this.currentOrientation === orientation)
       {
           return;
       }

       // Replace the adapter with an empty div during the rotate
       var viewerObject = this.controller.get('viewerObject');
       var emptyDiv = this.controller.document.createElement('div');
       emptyDiv.id = 'viewerObject';
       viewerObject.parentNode.replaceChild(emptyDiv, viewerObject);

       this.currentOrientation = orientation;
       this.controller.window.PalmSystem.setWindowOrientation(orientation);

       // Re-create the adapter
       this.dosetup();
*/
    },

    NeedPassword: function(docid) {

        this.document_id = docid;
        this.wrongpasscount++;

        this.controller.window.setTimeout(this.showPassword.bind(this), 250);
    },

    // TODO Called from a timeout to possibly fix a race condition????
    showPassword: function () {

        if (this.wrongpasscount === 0) {
            this.controller.get('PlugIn').hide();
        }

        var args = { name: 'password', disableSceneScroller: true };

        this.controller.stageController.pushScene(args, this);
    },

    PasswordCorrect: function() {

		this._hideLoadingSpinner();
        this.controller.get('PlugIn').show();

    },

    HasError: function(error_type) {
        Mojo.Log.warn("DocumentAssistant: HasError");

		if (this._loadingSpinnerTimeout) {
			this.controller.window.clearTimeout(this._loadingSpinnerTimeout);
			this._loadingSpinnerTimeout = null;
		}
		this._hideLoadingSpinner();

        switch (parseInt(error_type, 10)) {
            case 0:
                Mojo.Log.error("Open Document Error!");

                this.errorText = $L('Opening document failed');
                this.controller.window.setTimeout( this.showError.bind(this), 250);

                break;

            case 1:
                Mojo.Log.error("Render Document Error!");

                this.errorText = $L('Render document failed');
                this.controller.window.setTimeout( this.showError.bind(this), 250);

                break;

            case 2:
                Mojo.Log.error("Unsupported Encryption Error!");

                this.errorText = $L('Document encryption type not supported');
                this.controller.window.setTimeout( this.showError.bind(this), 250);

                break;

            default:
                Mojo.Log.error("Not handling this case: '%s'", error_type);
        }
    },

	executeJump: function ( pageNum ) {

		this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'jumpToPage',
			parameters: {
				docid: this.document_id,
				pageNum: pageNum
			},
            onSuccess: function(payload) {
                if ((payload.errorCode !== undefined) || (payload.curPage === undefined)) {
                    Mojo.Log.error("executeJump failed: " + Object.toJSON( payload ) );
                    return;
                }

                this.currentpage = payload.curPage;

            }.bind(this)
		});

	},

	updatePageFootOf: function () {

		if (this.currentpage !== undefined) {

			this.cmdMenuModel.items[1].items[0].disabled = (this.currentpage == 1);
			this.cmdMenuModel.items[1].items[2].disabled = (this.currentpage == this.pagecount);
			this.controller.modelChanged(this.cmdMenuModel);

			// rebind key event
			this.controller.listen(this.controller.get('page_foot_cur_ent'), 'keydown', this.handleFootPage);

			this.controller.get('page_foot_cur').innerHTML = this.currentpage;
			this.controller.get('page_foot_cnt').innerHTML = this.pagecount;
		}
	},

	showPageCnt: function () {
		this.updatePageFootOf();
		this.lastpage = this.currentpage;
	},

    // Jumps to the page "pageNumber"
	JumpToPage: function (pageNumber) {

        if (isNaN(pageNumber)) {
            return;
		}

		this.controller.window.clearTimeout(this.jumptimeout);
		this.jumptimeout = this.controller.window.setTimeout( this.executeJump(pageNumber), 500);
		this.showPageCnt();
    },

    // Change page number by "pages" number of pages
	ChangePagesBy: function (pages) {

		// Just make sure we are going to change pages
		if (pages === 0) {
			return;
		}

		this.startSpinner();

		this.currentpage += pages;
        this.JumpToPage( this.currentpage );
	},

    forceFootChange: function () {

        var goto_page = parseInt(this.controller.get('page_foot_cur_ent').value, 10);
        this.JumpToPage( goto_page );
    },

    turnOffPageFoot: function () {

        if (!this.pageFootEdit) {
			return;
		}

        this.forceFootChange();

        this.pageFootEdit = false;

		this.controller.get('command_pill').removeClassName('palm-depressed');
        this.controller.get('page_foot_ent').hide();
        this.controller.get('page_foot').show();

        this.updatePageFootOf();
    },

    // TODO Called from a timeout to possibly fix a race condition????
    showError: function () {

        this.controller.get('PlugIn').hide();
        this.controller.stageController.pushScene('error', this);
    },

    /*
     * Create the outline/bookmark data by getting it from the service, and then push the outline scene
     */
    createOutline: function () {

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'getOutline',
            parameters: { docid: this.document_id },
            onSuccess: function(payload) {
                if ((payload.errorCode !== undefined) || (payload.outlinearray === undefined)) {
                    Mojo.Log.error("getOutline failed get outlinearray: " + Object.toJSON( payload ) );
                    return;
                }

				this.controller.stageController.pushScene('outline', this, payload.outlinearray );

            }.bind(this),
            onFailure: function(payload) {
                Mojo.Log.error("getOutline failed: " + Object.toJSON( payload ) );
            }
		});
    },

	/**
	 * The drawing of the document happens in a thread and finishes sometime after it is opened.
	 * we don't want to remove the file open spinner until this open is complete.
	 */
	FirstDrawComplete: function() {
		Mojo.Log.info("First draw complete.");
		if (this._loadingSpinnerTimeout) {
			this.controller.window.clearTimeout(this._loadingSpinnerTimeout);
			this._loadingSpinnerTimeout = null;
		}
		var now = new Date();
		var minSpinnerDisplayTime = 1000;
		var remainingShowTime = this._spinnerShowTime + minSpinnerDisplayTime - now.getTime();
		if (remainingShowTime > 0) {
			this._loadingSpinnerTimeout = this.controller.window.setTimeout(this._hideLoadingSpinner, remainingShowTime);
		}
		else {
			this._hideLoadingSpinner();
		}
	},

	/*
	 *  This function is called from inside the adapter when it has finished loading the document!
	 */
	DocumentOpened: function(pagecnt, docid) {

		Mojo.Log.info("Successfully opened document %d with %d pages.", docid, pagecnt);
        this.document_id = docid;
		this.sceneActive = true;

        this.pagecount = pagecnt;

		// Set up the command buttons (footer)
		var page_len = (this.pagecount+'').length;
		this.cmdMenuModel.items[1].items[1].width = 60 + (page_len * 15);
		this.controller.modelChanged(this.cmdMenuModel);

		this.controller.setMenuVisible(Mojo.Menu.commandMenu, true);

        this.JumpToPage(this.currentpage);

    },

    doRender: function () {

        if (this.adapter.forceRender) {
            this.adapter.forceRender();
		}

        if (this.lastpage != this.currentpage) {
            this.showPageCnt();
        }
    },

    ReceiveJumpRenderDone: function(page) {

        if (page > 0) {
            this.currentpage = page;
            this.showPageCnt();
        }

        this.stopSpinner();
        this.controller.window.setTimeout( this.doRender.bind(this), 1000/30);
    },

    ActionRequest: function(command, arg) {

        var MsgResourceLinkClick = 1;
        var MsgIdleClick = 3;
        var MsgSearchResults = 14;

        Mojo.Log.info("DocumentAssistant : ActionRequest (%d, %s)", command, arg);

        switch(command) {
            case MsgIdleClick:

				this.showViewBar(true);
                break;

            case MsgSearchResults:
                Mojo.Log.info("Got search results.");

                this.resultCount = arg + '';

                this.showResult();
                break;

            case MsgResourceLinkClick:

                this.controller.serviceRequest('palm://com.palm.pdf/events', {
					method: 'getMimeInfo',
                    parameters: { docid: this.document_id },

                    onSuccess: function(payload) {

                        if ((payload.errorCode !== undefined) || (payload.link === undefined)) {
                            Mojo.Log.error("getMimeInfo failed get link: " + Object.toJSON( payload ) );
                            return;
                        }
                        //Mojo.Log.info("Mime payload: '%s'", payload.link);

                        var targetString = payload.link;

                        if (targetString.substr(0,7) == 'http://') {
                            var openParams = {
								scene: 'page',
								target: payload.link
							};
                            this.controller.serviceRequest('palm://com.palm.applicationManager', {
								method: 'open',
								parameters: {
									id: 'com.palm.app.browser',
									params: openParams
								}
                            });
                        }
                        else {
                            this.controller.serviceRequest('palm://com.palm.applicationManager', {
								method: 'open',
                                parameters: payload
                            });
                        }
                    },

                    onFailure: function(payload) {
                        Mojo.Log.error("getMimeInfo failed: " + Object.toJSON( payload ) );
                    }
                });
                break;

            default:
                Mojo.Log.error("Not handled: (%d, %s)", command, arg);
                break;
        }
    },

    handleFootPage: function(e) {

		if (e.keyCode == Mojo.Char.enter) {
			var goto_page = parseInt(this.controller.get('page_foot_cur_ent').value, 10);
            this.JumpToPage(goto_page);
			this.showFootPageOf();
		}
		else {
			var c = String.fromCharCode(e.keyCode).toLowerCase();
			var numeric = this.numericMap[c];
			if (numeric) {
				var input = this.controller.get('page_foot_cur_ent');
				if (input.selectionStart !== input.selectionEnd) {
					input.value = numeric;
				}
				else {
					input.value += numeric;
				}
			}
			else if (e.keyCode == Mojo.Char.backspace || e.keyCode == Mojo.Char.deleteKey) {
				// fall through
				return;
			}
			this.controller.window.event.returnValue = false;
		}
    },

    ready: function() {

		this._hideLoadingSpinner();
		this._loadingSpinnerTimeout = this.controller.window.setTimeout(this._showLoadingSpinner, 2000);

		// Set the view menu's spacer to be always 0 by calling a show.
		this.showViewBar(true);
    },

	_hideLoadingSpinner: function() {
		this._loadingSpinnerTimeout = null;
		this._loadingSpinner.mojo.stop();
		this.controller.get('loading-doc').hide();
	},

	_showLoadingSpinner: function(loading) {
		this._loadingSpinnerTimeout = null;
		this._loadingSpinner.mojo.start();
		this.controller.get('loading-doc').show();
		var now = new Date();
		this._spinnerShowTime = now.getTime();
	},

    updatePageFootOfEntry: function () {

        var page = undefined;
        var total_page = undefined;
        var page_len = '0';

        page = this.currentpage;
        total_page = this.pagecount;

        if (page !== undefined) {
            page_len = total_page + '';

            this.controller.get('page_foot_cur_ent').value = page;
            this.controller.get('page_foot_cnt_ent').innerHTML = total_page;
            this.controller.get('page_foot_cur_ent').size = page_len.length;
            this.controller.get('page_foot_cur_ent').maxLength = page_len.length;
            this.controller.get('page_foot_cur_ent').focus();
            this.controller.get('page_foot_cur_ent').select();
        }

        return page_len.length;
    },

    showFootPageOf: function () {

        if (!this.pageFootEdit) {

            this.showViewBar(true);

            this.pageFootEdit = true;

            this.controller.get('command_pill').addClassName('palm-depressed');
            this.controller.get('page_foot').hide();
            this.controller.get('page_foot_ent').show();
            this.controller.get('page_foot_cur_ent').setAttribute(Mojo.Gesture.consumesEnterAttribute, 'true');

            this.updatePageFootOfEntry();
        }
        else {
            this.showViewBar(true);
            this.turnOffPageFoot();
        }
    },

    _handleFocus: function(event) {

        this.adapter.setFocus(event.type == Mojo.Event.activate, this.documentPassword );

        this.turnOffPageFoot();
    },

    handleKeyDown: function(event) {
        var keyCode = event.originalEvent.keyCode;

		if (!this.sceneActive || this.pageFootEdit) {
			return;
		}

		if ( keyCode == Mojo.Char.metaKey ||
			keyCode == 129)	// Orange key
		{
			return;
		}
		if ( (keyCode != Mojo.Char.ctrl) &&
			 (keyCode != Mojo.Char.opt) &&
			 (keyCode <= Mojo.Char.deleteKey))
		{
			return;
		}
		if (keyCode >= 0xE000 && keyCode <= 0xF8FF)
		{
			// E000 ... F8FF is the unicode private use area, and used by the
			// platform (in some instances) as gesture navigation "keys".
			// Regardless, they are *not* valid printable characters.
			return;
		}

        if (!this.saveShowing && !this.findShowing) {
            this.showFind();
        }

		// If the findField does not have the focus, make it have focus
		if (this.findShowing) {
			this.findField.mojo.focus();
		}
    },

    _onTap: function(event) {

		var methodName = null;
        if (event.count == 1) {
			// If find is showing then we have to get rid of it
			if (this.findShowing) {
				this.hideFind();
			}
			else {
				methodName = 'handleClick';
			}
        }
        else if (event.count == 2) {
			methodName = 'handleDoubleClick';
        }

		var headerHeight = parseInt(this.controller.get('header').getStyle('height'), 10);
		var adapterDownY = event.down.screenY - headerHeight;

		if (methodName !== null) {
			this.controller.serviceRequest('palm://com.palm.pdf/events', {
				method: methodName,
                parameters: {
					docid: this.document_id,
					xCoord: event.down.screenX,
					yCoord: adapterDownY
				}
            });
		}
    },

    mousecheck: function (e) {
        // Make sure we are not in entry mode in the page of page
        this.turnOffPageFoot();
    },

    gestureStart: function(e) {

        this.adapter.gestureStart(e.scale, e.rotation);
    },

    gestureChange: function(e) {

        this.adapter.gestureChange(e.scale, e.rotation);
    },

    gestureEndCallAdapter: function(e) {
        this.adapter.gestureEnd(e.scale, e.rotation);
    },

    gestureEnd: function(e) {

        this.startSpinner();

        // Put this into a timer so that the spinner gets a chance to start spinning before the
        // CPU gets too busy doing the actual zooming

        // Is there not some way of making this happen after the spinner has started??
        this.controller.window.setTimeout(this.gestureEndCallAdapter(e), 250);
    },

    dosetup: function() {

		var headerHeight = parseInt(this.controller.get('header').getStyle('height'), 10);
        var new_obj = this.controller.document.createElement('object');
        new_obj.setAttribute('type', 'application/x-palm-pdfadapter');

		var width = this.controller.window.innerWidth;
		var height = this.controller.window.innerHeight - headerHeight;
		new_obj.setAttribute('width', width);
        new_obj.setAttribute('height', height);

        new_obj.setAttribute('id', 'viewerObject');
        new_obj.setAttribute('file', this.filename);
        new_obj.setAttribute('x-palm-pass-event', true);

        var replacement = this.controller.get('viewerObject');
        replacement.parentNode.replaceChild(new_obj, replacement);

        var splittext = this.filename.split('/');
        this.document_name = splittext[splittext.length-1];
        this.document_noext = this.document_name.substr(0, this.document_name.indexOf('.pdf'));
        this.controller.get('documentname').innerHTML = this.document_noext;
        new_obj.eventListener = this;

        this.adapter = new_obj;
    },

    flickcheck: function(event) {
        //Mojo.Log.info("DocumentAssistant: flickcheck");
        this.mousecheck();

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'handleFlick',
            parameters: {
				docid: this.document_id,
				xCoord: event.velocity.x,
				yCoord: event.velocity.y
			}
        });

        // This prevents a tap event when doing a flick
        event.stop();
    },

    openFilePicker: function () {

        // Right now lets just open a new window and send it to the recent scene
        this.controller.serviceRequest('palm://com.palm.applicationManager', {
            method: 'open',
            parameters: { 'id': 'com.palm.app.pdfviewer' }
        });
    },

    handleCommand: function(event) {

        if (event.type == Mojo.Event.commandEnable) {
            if (event.command == Mojo.Menu.helpCmd) {
                event.stopPropagation();
            }
        }

        if (event.type == Mojo.Event.command) {
			try {

				switch (event.command) {
					case 'file-open-cmd':
						this.openFilePicker();
						break;

					case 'file-saveas-cmd':
						this.saveAsDialog();
						break;

					case 'share-cmd':
						this.shareDocument();
						break;

					case 'find-cmd':
						if (this.findShowing) {
							this.hideFind();
						}
						else {
							this.showFind();
						}
						break;

					case 'prev-cmd':
						this.ChangePagesBy(-1);
						break;

					case 'next-cmd':
						this.ChangePagesBy(+1);
						break;

					case 'edit-cmd':
						this.showFootPageOf();
						break;

					case 'pdf-outline':

						// Create the PDF outline/bookmarks
						this.createOutline();

						break;

					case 'pdf-pageof':
						this.controller.stageController.pushScene('pagetext', this);
						break;

					case Mojo.Menu.helpCmd:
						//Mojo.Log.info("Help command for pdfviewer");

						this.controller.serviceRequest('palm://com.palm.applicationManager', {
							method: 'open',
							parameters: {
								id: 'com.palm.app.help',
								params: {
									target: "http://help.palm.com/pdf_view/index.html"
								}
							}
						});

						break;
				}
			}
			catch (e) {
				Mojo.Log.logException(e);
			}
        }
    },

    findIndex: function(model, what) {

        for (var i = 0; i < model.items.length; i++) {
            if (model.items[i].command == what) {
                return i;
            }
        }
        return -1;
    },

    // check or uncheck the bookmark menu item
    updateBookmarksMenuItem: function(hasOutline) {
        var index = this.findIndex(this.appMenuModel, 'pdf-outline');
        this.appMenuModel.items[index].enabled = hasOutline;

        this.controller.modelChanged(this.appMenuModel);
    },

    showViewBar: function(visible) {

        if (!this.findShowing) {
			// Do NOT animate the menu spacer away because we've disabled it for
			// for our needs
			var menuAssistant = this.controller._menu.assistant;
			menuAssistant.viewSpacerHeight = 0;

            this.controller.setMenuVisible(Mojo.Menu.viewMenu, visible);
        }
    },

    propertiesDialog: function() {

        this.controller.showDialog({
            template: 'document/properties-dialog',
            assistant: new PropertiesDialogAssistant(this)
        });
    },

    optionsDialog: function() {

        this.controller.showDialog({
            template: 'document/options-dialog',
            assistant: new OptionsDialogAssistant(this)
        });
    },

    saveAsDialog: function() {

        this.controller.showDialog({
            template: 'document/saveas-dialog',
            assistant: new SaveAsDialogAssistant(this)
        });
    },

    showFind: function() {

        this.showViewBar(false);

        this.toggleMenuCheck('find-cmd', true);

        this.findField.mojo.showFind();
        this.findShowing = true;
    },

    closeSearch: function () {

        // Clear the find strings
        this.findString = '';
        this.newFindString = '';

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'closeSearch',
            parameters: {
				docid: this.document_id
			}
        });
    },

    hideFind: function() {

        this.toggleMenuCheck('find-cmd', false);

        if (this.findShowing) {
            this.closeSearch();
        }

        this.findShowing = false;
        this.findField.mojo.hideFind();

        this.showViewBar(true);
    },

    handleFind: function(event) {

        this.findCancel = false;
        this.newFindString = event.findString;

        if (this.newFindString.length > 0 && this.findString != this.newFindString) {
            if (this.findString !== '') {
                this.closeSearch();
            }

            this.findString = event.findString;
            this.resultCount = '0';

            this.submitSearch(this.findString);
        }
    },

    handleFindClear: function(event) {

        this.hideFind();
    },

    submitSearch: function(value) {

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'doSearch',
            parameters: {
				docid: this.document_id,
				search: value
			},
            onSuccess: function(payload) {

                if ((payload.errorCode !== undefined) || (payload.resultcount === undefined)) {
                    Mojo.Log.error("Search failed get resultcount: " + Object.toJSON( payload ) );
                    return;
                }

                this.resultCount = payload.resultcount;
                this.showResult();
            }
        });
    },

    handleFindGo: function(event) {

        this.newFindString = event.findString;
        this.findCancel = event.cancel;

        if (this.findCancel) {
            this.closeSearch();
        }
        else {
            if (this.newFindString.length > 0 && this.findString != this.newFindString) {

                if (this.findString !== '') {
                    this.closeSearch();
                }

                this.findString = event.findString;
                this.resultCount = '0';

                this.submitSearch(this.findString);
            }
            else if (this.findString == this.newFindString) {
                this.showResult();
            }
        }
    },

    handleFindPrev: function(event) {

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'previousResult',
            parameters: {
				docid: this.document_id
			}
		});
    },

    handleFindNext: function(event) {

        this.controller.serviceRequest('palm://com.palm.pdf/events', {
			method: 'nextResult',
            parameters: {
				docid: this.document_id
			}
		});

    },

    showResult: function() {
        Mojo.Log.info("DocumentAssistant: showResult");

        this.findField.mojo.showResult(this.resultCount);
    },

    stopSpinner: function() {

        this.spinnerRunning = false;
        this.spinnerModel.p = false;
        this.controller.modelChanged(this.spinnerModel);
    },

    startSpinner: function() {

        this.spinnerRunning = true;
        this.spinnerModel.p = true;
        this.controller.modelChanged(this.spinnerModel);
    },

    shareDocument: function() {

        this.controller.serviceRequest('palm://com.palm.applicationManager', {
            method: 'open',
            parameters: {
                id: 'com.palm.app.email',
                params: {
					attachments: [{
						fullPath: this.filename,
						displayName: this.document_name
					}]
				}
            }
        });
    },

    toggleMenuCheck: function(command, on_off) {

        var index = this.findIndex(this.appMenuModel, command);
        if (index != -1) {
            this.appMenuModel.items[index].chosen = on_off;
        }
    }
});



PropertiesDialogAssistant = Class.create({

    initialize: function(documentAssistant) {

        this.documentAssistant = documentAssistant;
    },

    setup: function(widget) {

        this.widget = widget;

        this.controller.get('propertiesText').addEventListener(Mojo.Event.tap,
                                             this.onClose.bind(this));
    },

    activate: function() {

        this.documentAssistant.controller.get('palm-dialog-box').style.top = '40px';
        this.documentAssistant.controller.get('palm-dialog-box').style.bottom = 'auto';
    },

    onClose: function() {

        this.widget.mojo.close();
    }
});


OptionsDialogAssistant = Class.create({

    initialize: function(documentAssistant) {

        this.documentAssistant = documentAssistant;
    },

    setup: function(widget) {

        this.widget = widget;

        this.documentAssistant.controller.get('open_button').addEventListener(Mojo.Event.tap,
                                          this.onOpen.bind(this));

        this.documentAssistant.controller.get('saveas_button').addEventListener(Mojo.Event.tap,
                                            this.onSaveAs.bind(this));

        this.documentAssistant.controller.get('cancel_button').addEventListener(Mojo.Event.tap,
                                            this.onCancel.bind(this));
    },

    onOpen: function() {

        this.widget.mojo.close();
        this.documentAssistant.openFilePicker();
    },

    onSaveAs: function() {

        this.widget.mojo.close();
        this.documentAssistant.saveAsDialog();
    },

    onCancel: function() {

        this.widget.mojo.close();
    }
});


SaveAsDialogAssistant = Class.create({

    initialize: function(documentAssistant) {

        this.documentAssistant = documentAssistant;
        this.saveModel = this.documentAssistant.saveModel;
    },

    setup: function(widget) {

        this.widget = widget;

        this.documentAssistant.controller.get('save_button').observe(Mojo.Event.tap,
                                 this.onSave.bind(this));

        this.documentAssistant.controller.get('cancel_button').observe(Mojo.Event.tap,
                                   this.onCancel.bind(this));
    },

    activate: function() {

        this.documentAssistant.saveShowing = true;

        this.saveModel.original = this.documentAssistant.document_noext;
        this.documentAssistant.controller.modelChanged(this.saveModel);
        this.documentAssistant.controller.get('text_field').mojo.focus();
    },

    deactivate: function() {
        this.documentAssistant.saveShowing = false;
    },

    onSave: function() {

        var textField = this.documentAssistant.controller.get('text_field');
        var temp = textField.mojo.getValue();
        if (!temp || (temp.length === 0))
        {
            // If the string is empty, don't do anything - they must cancel or enter a valid string
            // Put the focus back into the text field
            this.documentAssistant.controller.get('text_field').mojo.focus();
            return;
        }

        // Not going to allow quotes or semi-colons at this time
        var save_input = temp.replace(/"/g, '').replace(/;/g, '');

        if (save_input !== undefined && save_input.length > 0) {

            var file = [];

            file = save_input.split('.');

            var type = file[file.length-1];

            if (type != 'pdf') {
                save_input = save_input + '.pdf';
            }

            // If we have a filename
            if (this.documentAssistant.filename !== undefined && this.documentAssistant.filename != 'unspecified file')
            {
                var new_filename = '';
                var dir = '/media/internal';

                /*
                 * NOV-36964 always store the file in the /media/internal dir
                 *
                var path = new Array();
                var dir = '';

                path = this.documentAssistant.filename.split('/');

                for (var i = 1; i < path.length - 1; i++)
                    dir = dir+'/'+path[i];
                 *
                 */

                new_filename = dir+'/'+save_input;

                if (new_filename != this.documentAssistant.filename)
                {
                    try
                    {
                        this.documentAssistant.adapter.saveAs(this.documentAssistant.filename, new_filename);

                        // Reset some globals
                        this.documentAssistant.filename = new_filename;
                        this.documentAssistant.document_name = save_input;
                        this.documentAssistant.document_noext = this.documentAssistant.document_name.substr(0, this.documentAssistant.document_name.indexOf('.pdf'));

                        this.documentAssistant.controller.get('documentname').innerHTML = this.documentAssistant.document_noext;

                    }
                    catch(e)
                    {
                        Mojo.Log.logException(e);
                    }
                }

            }
        }

        this.widget.mojo.close();
    },

    onCancel: function() {

        this.widget.mojo.close();
    }

});
