/*	
 Copyright 2014 Adobe Systems Incorporated.  All rights reserved. 
*/
// JavaScript Document

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, maxerr: 50 */
/*global document, dw, smDwRetryLoadFromServer, DWfile, dWWriteLog, AdobeHello*/

//Globals
var brsDoc;
var brsCtrl;
var browserWin;

var offlineURL           = "";
var onlineURL            = "";
var bridgeJS             = "/Content/HelloWelcome/HTML5/scripts/dwhellobridge.js";
var isInited             = false;

var defaultJSONListSize  = 10;
var newDocTypeURLs       = {};
var recentFilesURLs      = {};
var retRecentFilesJSON   = "";
var currentTab           = "";
var offlineContentLoaded = false;

// Icons used in Hello
var dwGenericIcon        = "DWFile";
var templateIcon         = "Templates";
var templateFolderIcon   = "openicon";

// Bug fix #3860495. Actually this is bug in Hello. fullPath that we are passing to Hello, is not 
//reorganized. Instead they use index of Recent file list. 
var openCommandIndex     = 0;
var lastHelloShowFlag     = false;

// String for Headlight catagory & subcatagory
// Refer UT_HELLO_DATA, UT_HELLO_FAILURE & UT_HELLO_INTERACTION in usagetracking.h
var helloCatagoryStr    = "ProjectHello";
var helloInteractionStr = "Interaction";
var helloFailureStr     = "Failure";
var helloNewDocStr		= "New Document created from welcome screen";

var openFileJSON = "{\"icon\":\"openicon\",\"tip\":\"Select an existing file to work with.\",\"name\":\"Open...\",\"fullpath\":\"open\"}";

var specialDocs = [{ "label": "Site", "url": "mminternal:newsite", "icon": "Site" }];

var moreTemplate = [{"label": "More...", "url": "mminternal:newtemplate"}];
var newDocumentFromHello = "mminternal:newdocument:fromhello=";

//get file type from internal url (Dreamweaver style)
function getLocalizedDocTypeString(docType, type, customType) {
	"use strict";
	// NOTE: No localization strings added for hello as it is supported only in English. 
	// But the purpose of this function to support other locales in future.
	// Please follow the comments in this function for adding/querying localized 
	// strings in future.

	if (type === "tip") {
		// Unique Key is "Hello/<docType>/tip" where docType is
		// HTML, CSS, JS, PHP, and so on.
		// Use this key for adding local string and invoke dw.loadString(key).
		var docTypeName = docType + " Document";
		if (docType === "Multi") {
			docTypeName = "Fluid Grid Document";
		} else if (docType === "Site") {
			docTypeName = "Site";
		} else if (docType === "More...") {
			return "";
		} else if (customType) {
			docTypeName = docType;
		}
		return "Click to create a new " + docTypeName;
	}

	if (type === "") {
		if (docType === "Site") {
		    return "Dreamweaver Site";
		}
		if (docType === "Multi") {
		    return "Fluid Grid Document";
		}
		if (docType === "Templates") {
			return "Starter Templates";
		}
		if (customType) {
			return docType;
		}
	}

	return (docType + " Document");
}

 /*
 The below is the expected JSON string for newDocTypes for Hello.
 {"newDocTypes":[{"icon":"museicon_small",
					"tip":"Click to create a new site.",
					"name":"Site",
					"docType":"site"
				}]} 
 */
function getDocTypeJSONStr(docTypeArray, useGenericIcon, customIcon, maxCount) {
	"use strict";
    if ("undefined" === (typeof docTypeArray) || docTypeArray === null) {
        dWWriteLog("docTypeArray null");
        return;
    }
	if ("undefined" === (typeof maxCount) || maxCount === null) {
		// set it to default.
		maxCount = defaultJSONListSize;
	}

	var i, str = "";
	for (i = 0; i < docTypeArray.length; i++) {
		if (i >= maxCount) {
			break;
		}

		if (i > 0) {
			str += ",";
		}

		str += "{\"docType\":\"" + docTypeArray[i].label + "\",";
		str += "\"name\":\"" + getLocalizedDocTypeString(docTypeArray[i].label, "", customIcon) + "\",";
		str += "\"tip\":\"" + getLocalizedDocTypeString(docTypeArray[i].label, "tip", customIcon) + "\",";
		if (useGenericIcon) {
			str += "\"icon\":\"" + dwGenericIcon + "\"}";
		} else {
		    var icon = docTypeArray[i].icon;
			if (customIcon) {
				icon = customIcon;
			} else if (!icon) {
			    icon = docTypeArray[i].label;
			}
			str += "\"icon\":\"" + icon + "\"}";
		}

		newDocTypeURLs[docTypeArray[i].label] = docTypeArray[i].url;
    }

	return str;
}

// get list of starter Templates in JSON format
function getStarterTemplateJSON() {
	"use strict";
	var i, str = "",
		maxCount = defaultJSONListSize,
		templateLst = dw.startPage.templateList;
	for (i = 0; i < templateLst.length; i++) {
        if (typeof templateLst[i].list === 'undefined' || templateLst[i].list === null) {
            continue; // skip a blank list.
        }
		if (str.length > 0 && maxCount > 0) {
			str += ",";
		}
		str += getDocTypeJSONStr(templateLst[i].list, false, templateIcon, maxCount);

		var templateLen = templateLst[i].list.length;
		if (templateLen > maxCount) {
			str += ",";
			str += getDocTypeJSONStr(moreTemplate, false, templateFolderIcon, 1);
			break;
		}
		maxCount -= templateLst[i].list.length;
	}
	str = "\"templateTypes\":[" + str + "]";
	return str;
}

//get list of new doc types in JSON format
function getNewDocsTypeJSON() {
	"use strict";
	newDocTypeURLs = {};

	var str = getDocTypeJSONStr(dw.startPage.newFileList, true);

	if (str.length > 0) {
		str += ",";
	}

	str += getDocTypeJSONStr(specialDocs, false);

	str = "\"newDocTypes\":[" + str + "]";

	return str;
}

/*
The below is the expected JSON format for recentFiles.
recentFiles":[{"icon":"museicon_small",
				"tip":"/file/path/to/the/file_name.muse",
				"name":"ProjectHelloMockup",
				"fullpath":"0"
				},
			  {"icon":"museicon_small",
			  "tip":"/file/path/to/the/file_name.muse",
			  "name":"onboarding",
			  "fullpath":"1"},....]
*/
function getRecentFilesJSONStr() {
	"use strict";
	// reinitialize recent file list.
	recentFilesURLs = {};

	var mruArray = dw.startPage.recentFileList;
	var i, toolTip, str = "";
	for (i = 0; i < mruArray.length; i++) {
		if (i > 0) {
			str += ",";
		}

		toolTip = mruArray[i].url.substring(32);
		toolTip = toolTip.replace('|', ':');

		str += "{\"fullpath\":\"" + i + "\",";
		str += "\"name\":\"" + mruArray[i].label + "\",";
		str += "\"tip\":\"" + toolTip + "\",";
		str += "\"icon\":\"" + dwGenericIcon + "\"}";

		// Remember index and file URL
		recentFilesURLs["" + i] = mruArray[i].url;
    }

	// remember index for open dialog entry
	openCommandIndex = mruArray.length;

	if (str.length > 0) {
		str += ",";
	}

	str += openFileJSON;
	str = "\"recentFiles\":[" + str + "]";

	return str;
}

/*
Construct and return application and user specific Hello configuration JSON String and return.
Please refer "Hello Configuration Data" section in 
	https://wiki.corp.adobe.com/display/hello/Desktop+Product+Integration+Info+-+V1.5
*/
function getHelloConfigJSONStr() {
	"use strict";
	// remember the recent file JSON to track modification in 
	// recentfile list.
	retRecentFilesJSON = getRecentFilesJSONStr();

	lastHelloShowFlag = dw.startPage.shouldShow;

	// construct hello JSON
	var appInfo = dw.startPage.helloConfigJSON + ", \"dontShowAgain\": " + (dw.startPage.shouldShow ? "\"false\"" : "\"true\"");

	// append doc types and recent files
	appInfo = "{" + appInfo + "," + getNewDocsTypeJSON() + "," + getStarterTemplateJSON() + "," + retRecentFilesJSON + "}";

	dWWriteLog("<AdobeHello> Host-app JSON: " + appInfo);
	return appInfo;
}

/*
 Refresh Hello page if required. We should do it when there is 
change in recent file lists.
*/
function refreshHelloIfRequired() {
	"use strict";

	// Check whether there is any change in recent file list.
	var recentFiles = getRecentFilesJSONStr();

	if (browserWin
			&& (
				(recentFiles !== retRecentFilesJSON && (offlineContentLoaded || currentTab === "create"))
				|| lastHelloShowFlag !== dw.startPage.shouldShow
			)) {
		dWWriteLog("Refressh Hello");
		retRecentFilesJSON = recentFiles;
		// TODO: To avoid full reloading, we have asked an API in hello
		// to just refresh recent file list.
		smDwRetryLoadFromServer(true);
	}

}

/*
 Log message
*/
function dWWriteLog(str) {
	"use strict";
	if (browserWin && browserWin.dwHelloBridgeInitializer) {
		browserWin.dwHelloBridgeInitializer.dWLog("SM :" + str);
	}
}

/*
 Call back function for Hello hostAppGetPersonalizationInfo.
 Upon receiving this callback, the host application should build a JSON string 
 return that string to the caller.
*/
function getSmDwUserJsonData(callbackObj) {
	"use strict";
	dWWriteLog("trace: getSmDwUserJsonData");
	callbackObj.rawJsonData(getHelloConfigJSONStr());
}

/*
 Call back function for Hello hostAppOpenDoc.
 Upon receiving this callback, the host application should log this event in headlights 
 and open the file with the specified file path.
*/
function openExistingSmDwDocument(fullPath) {
	"use strict";
	dWWriteLog("trace: openExistingSmDwDocument: " + fullPath);

	// Get/construct command string.
	var openFileCommandStr = null;

	if (fullPath === "open" || fullPath === openCommandIndex) {
		openFileCommandStr = "mminternal:opendocument=";
	} else {
		openFileCommandStr = recentFilesURLs["" + fullPath];
	}

	if (openFileCommandStr) {
		dw.startPage.doAction(openFileCommandStr);
		dw.startPage.hideStartupPage();
	}

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "OpenExistingDoc");
}

/*
 Call back function for Hello hostAppCreateNewDoc.
 Upon receiving this callback, the host application should log this event in headlights 
 and create a document of the specified type. suppressNewDocUI is NOP for DW.
*/
function openSmDwDocumentOfType(documentType, suppressNewDocUI) {
	"use strict";
	dWWriteLog("trace: openSmDwDocumentOfType: " + documentType + " : " + suppressNewDocUI);

	var command;
	if(dw.startPage.recentFileList && dw.startPage.recentFileList.length <= 0)
		command	= newDocumentFromHello;
	else
		command = newDocTypeURLs[documentType];

	if (command) {
		dw.startPage.doAction(command);
	}

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "CreateNewDoc");
	dw.logEvent(helloNewDocStr, documentType);
}

/*
 Call back function for Hello hostAppCreateNewDoc.
 Upon receiving this callback, the host application should log this event in headlights 
 and create a document of the specified type. suppressNewDocUI is NOP for DW.
*/
function smDwSetHelloDontShowAgainPreference(dontShowAgain) {
	"use strict";
	dWWriteLog("trace: smDwSetHelloDontShowAgainPreference: " + dontShowAgain);
	dw.startPage.shouldShow = (dontShowAgain ? false : true);
	lastHelloShowFlag = dw.startPage.shouldShow;

	if (dontShowAgain) {
		dw.logEvent(helloCatagoryStr, helloInteractionStr, "SetDoNotShowAgain");
	} else {
		dw.logEvent(helloCatagoryStr, helloInteractionStr, "ClearDoNotShowAgain");
	}
}

/*
 Call back function for Hello hostAppRetryLoadFromServer.
 Upon receiving this callback, the host application should log this event in headlights 
 and then try to reload the Hello HTML content from the remote server. 
*/
function smDwRetryLoadFromServer(forceReload) {
	"use strict";
	dWWriteLog("trace: smDwRetryLoadFromServer");

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "RetryPageLoad");

	if ("undefined" === (typeof forceReload) || forceReload === null) {
		forceReload = false;
	}

	// Check whether we are in online
	if (dw.startPage.isConnectedToInternet) {
		// load online content.
		brsCtrl.openURL(onlineURL);
		dw.logEvent(helloCatagoryStr, helloInteractionStr, "DisplayRemoteHello");
		offlineContentLoaded = false;
	} else {
		if (forceReload || !offlineContentLoaded) {
			// load offline content.
			offlineContentLoaded = true;
			brsCtrl.openURL(offlineURL);
			dw.logEvent(helloCatagoryStr, helloInteractionStr, "DisplayOfflineHello");
		}
	}
}

/*
 Call back function for Hello hostAppNotifyDoneWithUI.
 Upon receiving this callback, the host application should log this event 
 in headlights and remove the dialog from the screen. 
*/
function smDwNotifyDoneWithDialog() {
	"use strict";
	dWWriteLog("trace: smDwNotifyDoneWithDialog");

	dw.startPage.hideStartupPage();

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "DoneWithDialog");
}

/*
 Call back function for Hello hostAppNotifyFailedToLoad.
 Upon receiving this callback, the host application should record the error using headlights 
 and then fall back to loading Hello HTML content from the local disk. 
*/
function smDwNotifyFailedToLoad(errorString) {
	"use strict";
	dWWriteLog("trace: smDwNotifyFailedToLoad: " + errorString);

	// Load offline content.
	brsCtrl.openURL(offlineURL);
	offlineContentLoaded = true;

	if (errorString) {
		dw.logEvent(helloCatagoryStr, helloFailureStr, errorString);
	}
}

/*
 Call back function for Hello hostAppOpenLinkInDefaultBrowser.
 Upon receiving this callback, the host application should load the URL in external browser.
*/
function smDwOpenLinkInDefaultBrowser(url) {
	"use strict";
	dWWriteLog("trace: smDwOpenLinkInDefaultBrowser: " + url);
    // We pass a special 2nd parameter for browser, "HelloSysDefault"
    // Opening URLs for hello needs special handling on Mac, see watson 3934631
	dw.browseDocument(url, "HelloSysDefault");

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "OpenExtLink:" + url);
}

/*
 Call back function for Hello hostAppNotifyInContentTutorial.
 Upon receiving this callback, if the value passed in is 'true' then the host application 
 should not do autohiding of the Hello UI.
*/
function smDwNotifyInContentTutorial(isInContentTutorial) {
	"use strict";
	dWWriteLog("trace: smDwNotifyInContentTutorial: " + isInContentTutorial);
	dw.startPage.helloInTutorial = isInContentTutorial;

	if (isInContentTutorial) {
		dw.logEvent(helloCatagoryStr, helloInteractionStr, "InContentTutorial");
	} else {
		dw.logEvent(helloCatagoryStr, helloInteractionStr, "OutContentTutorial");
	}
}

/*
 Call back function for Hello hostAppNotifyContentTabChanged.
 Upon receiving this callback, the host application should clear helloInTutorial.
*/
function smDwNotifyContentTabChanged(currTab) {
	"use strict";
	dWWriteLog("trace: smDwNotifyContentTabChanged: " + currTab);

	currentTab = currTab;

	dw.startPage.helloInTutorial = false;

	// Refresh Hello recent files if requried
	if (currentTab === "create") {
		refreshHelloIfRequired();
	}

	dw.logEvent(helloCatagoryStr, helloInteractionStr, "In Tab:" + currTab);
}

//This will be called once loading webview is done.
function browserControlLoaded() {
	"use strict";
	try {
		browserWin = brsCtrl.getWindow();

		browserWin.dwBridge = {
			hostAppGetPersonalizationInfo			:	getSmDwUserJsonData,
			hostAppOpenDoc						    :	openExistingSmDwDocument,
			hostAppCreateNewDoc			            :	openSmDwDocumentOfType,
			hostAppSetDoNotShowAgainPreference		:	smDwSetHelloDontShowAgainPreference,
			hostAppRetryLoadFromServer	            :	smDwRetryLoadFromServer,
			hostAppNotifyDoneWithUI		            :	smDwNotifyDoneWithDialog,
			hostAppNotifyFailedToLoad	            :	smDwNotifyFailedToLoad,
			hostAppNotifyHTMLLayoutComplete			:	smDwNotifyFailedToLoad,
			hostAppSendBackTest						:	smDwNotifyFailedToLoad,
			openURLInDefaultBrowser					:	smDwOpenLinkInDefaultBrowser,
			hostAppNotifyInContentTutorial			:	smDwNotifyInContentTutorial,
			hostAppNotifyContentTabChanged          :	smDwNotifyContentTabChanged,
			enableLog                               :   false
		};

		var script = DWfile.read(dw.getConfigurationPath() + bridgeJS);
		brsCtrl.evalJS(script);

		// Send App configuration JSON string to Hello.
		browserWin.DWOnLoaded(getHelloConfigJSONStr());

	} catch (exception) {
		dWWriteLog("<AdobeHello> EXCEPTION: Brower loading failed");
    }
}

//Initialize the view and load webview
function initializeUI() {
	"use strict";
    if (isInited === false) {
        brsCtrl = document.getElementById("browser_welcome_screen");

        brsCtrl.addEventListener("BrowserControlLoad", browserControlLoaded, true);

        // create Hello control objects
        var adobeHello       = new AdobeHello('DRWV');
        var productInterface = adobeHello.getProductInterface();

        // set the default online/offline url's
        offlineURL = dw.getConfigurationPath() + productInterface.url.offline;
        onlineURL  = productInterface.url.online;

        var helloURL = offlineURL;

		// Check whether we are in online (and not forcing offline for debuggin!)
		if (dw.startPage.isConnectedToInternet && !adobeHello.forceOffline) {
			// load online content
            helloURL  = onlineURL;
			dw.logEvent(helloCatagoryStr, helloInteractionStr, "DisplayRemoteHello");
			offlineContentLoaded = false;
		} else { // load offline content
			offlineContentLoaded = true;
			dw.logEvent(helloCatagoryStr, helloInteractionStr, "DisplayOfflineHello");
		}
        dWWriteLog("<AdobeHello> Loading URL:" + helloURL);
        brsCtrl.openURL(helloURL);
        isInited = true;
    }

	// This is getting called whenever all open documents closed
	// Refresh if there is any change in recent file list.
	refreshHelloIfRequired();
}

// Callback on resize UI
function resizeUI() {
	"use strict";
	dWWriteLog("trace: resizeUI inited:" + isInited);

    if (isInited === false) { initializeUI(); }

	var asyncResize = function() {
        if (brsCtrl && brsCtrl.style) {
            brsCtrl.style.height = window.innerHeight + "px";
            brsCtrl.style.width  = window.innerWidth  + "px";
        }
    };
    // Resize immediatly
    asyncResize();
    // and resize again asynchronously because of a bug in TitanView paginator.
    // Watson 3862510
    setTimeout(asyncResize, 50);
}

// Callback on show UI
function onShow() {
	"use strict";
	dWWriteLog("trace: onShow inited:" + isInited);
	refreshHelloIfRequired();
}
