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

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, maxerr: 50 */
/*global document, dw, dWWriteLog, DW_NDD_CONSTANTS, DWfile, Bootstrap, LOGGING_CONSTANTS, DWUri, getBootstrapCss, getBootstrapJsScript, getBootstrapJqueryScript, getBootstrapGlyphFonts, AssetInfo*/

//Globals
var gNDDBrowserCtrl = null;
var gNDDBrowserWin = null;
var gIsNDDInited = false;
var gNDDBrowserUIInputs = null;
var gBootstrapGeneratedPath = null;
var gNDDLocalStrings = {};


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

/*
 Get Locale String
*/
function getLocalString(key) {
	"use strict";
	return gNDDBrowserWin.browserbridge.getLocalizedString(key);
}

/*
 Get user inputs from browser View.
*/
function getSelectedParameters() {
	"use strict";
	if (!gNDDBrowserUIInputs && gNDDBrowserWin && gNDDBrowserWin.browserbridge) {
		gNDDBrowserUIInputs = gNDDBrowserWin.browserbridge.getSelectedNewDocPreference();
	}
	return gNDDBrowserUIInputs;
}

function setBootstrapAsCurrentTab() {
    "use strict";
	if (gNDDBrowserWin && gNDDBrowserWin.browserbridge) {
		gNDDBrowserWin.browserbridge.selectBootstrapTab();
	}
}

/*
 Validate user inputs in browser View.
*/
function validateUI() {
	"use strict";
	if (gNDDBrowserWin && gNDDBrowserWin.browserbridge) {
		//alert ("TODO - Validate UI inputs");
		//return gNDDBrowserWin.browserbridge.validateUI();
		return true;
	}
	return false;
}

/*
 Call back for Bootstrap Node request success
*/
function callbackOnBootstrapSuccess(outFileName) {
	"use strict";
	dWWriteLog("Successfuly created " + outFileName);
	// Mark it as "read only"
    dw.ndd.makeFileAsReadOnly(outFileName);
	dw.ndd.notifyBootstrapCreated();
}

/*
 Call back for Bootstrap Node request failure/error
*/
function callbackOnBootstrapError(outFileName, errType, errMsg) {
	"use strict";
	gBootstrapGeneratedPath = null;
	gNDDBrowserUIInputs = null;
	dWWriteLog("Error in creating " + outFileName + " : " + errMsg);
	dw.ndd.notifyBootstrapCreationError();
	gNDDBrowserWin.browserbridge.notifyBootstrapCreationError();
    dw.logEvent(LOGGING_CONSTANTS.NDD_Layout, LOGGING_CONSTANTS.Bootstrap_NDD_CustomizeFailed);
}


/*
 Generate CSS dynamically using service.
*/
function generateCSSFromNode(cssOutPath, uiOptions) {
	"use strict";

	// Remove "read only"
	if (DWfile.exists(cssOutPath)
			&& DWfile.getAttributes(cssOutPath).indexOf("R") !== -1) {
		DWfile.setAttributes(cssOutPath, "W");
	}
	DWfile.remove(cssOutPath);

    var ret = false;
    try {
		// remove bootstrapp.css from path as it is geting added automatically
		var n = cssOutPath.lastIndexOf(DW_NDD_CONSTANTS.BootstrapFile),
			newPath = cssOutPath.substring(0, n);
		gBootstrapGeneratedPath = newPath;
		dWWriteLog("newPath :" + newPath);

		if (uiOptions.screenSm === DW_NDD_CONSTANTS.ScreenSmDefault
				&& uiOptions.screenMd === DW_NDD_CONSTANTS.ScreenMdDefault
				&& uiOptions.screenLg === DW_NDD_CONSTANTS.ScreenLgDefault
				&& uiOptions.numberOfCol === DW_NDD_CONSTANTS.NumberOfColDefault
				&& uiOptions.gutterWidth === DW_NDD_CONSTANTS.GutterWidthDefault) {

			// Generate default bootstrap.css
			ret = Bootstrap.generateDefault(newPath, {
				"success": callbackOnBootstrapSuccess,
				"error": callbackOnBootstrapError
			});

			dWWriteLog("Invoked Bootstrap.generateDefault");
		} else {

			// Generate custom bootstrap.css
			ret = Bootstrap.generateCustom(newPath, {
				"small-min": uiOptions.screenSm + "px",
				"medium-min": uiOptions.screenMd + "px",
				"large-min": uiOptions.screenLg + "px",
				"num-columns": uiOptions.numberOfCol + "",
				"gutter-width": uiOptions.gutterWidth + "px",
				"success": callbackOnBootstrapSuccess,
				"error": callbackOnBootstrapError
			});

			dWWriteLog("Invoked Bootstrap.generateCustom");
		}

		dWWriteLog("Generate bootstrap.css retuns :" + ret);
	} catch (e) {
		dWWriteLog("Generate bootstrap.css throws exception :" + e.message);
		return false;
	}
	if (ret) {
		dWWriteLog("cssOutPath :" + cssOutPath);
		// Remember the bootstrap path for subsequent
		// page creation.
		dw.ndd.setLastUsedBootstrapPath(cssOutPath);
	}
	return ret;
}

/*
Is UI bootstrap settings are of default values
*/
function isUIBootstrapUseDefaultSettings(uiOptions) {
	"use strict";
	return (uiOptions.screenSm === DW_NDD_CONSTANTS.ScreenSmDefault
			&& uiOptions.screenMd === DW_NDD_CONSTANTS.ScreenMdDefault
			&& uiOptions.screenLg === DW_NDD_CONSTANTS.ScreenLgDefault
			&& uiOptions.numberOfCol === DW_NDD_CONSTANTS.NumberOfColDefault
			&& uiOptions.gutterWidth === DW_NDD_CONSTANTS.GutterWidthDefault);
}

/*
Copy all the bootstrap files into target path
*/
function copyBootstrapBundleIntoDir(path) {
	"use strict";
	var builtinBootstrap = dw.getUserConfigurationPath() + DW_NDD_CONSTANTS.BootstrapBundle,
		builtinBootstrapURI = new DWUri(builtinBootstrap),
		srcDir = builtinBootstrapURI.toLocalPath(),
		nddObj = dw.ndd;

	if (!nddObj) {
		return;
	}

	dWWriteLog("Copying Bootstrap bundle into " + path);
	if (!nddObj.copyDirectory(srcDir, path)) {
		dWWriteLog("Error while copying Bootstrap bundle from " + srcDir + " into " + path);
	}
}

/*
Get the required assetList for creating the document
*/
function getAssetListForDocCreation() {
    "use strict";
    var assetList = [], i, assetInfo, bootstrapCssAsset, bootstrapJsAsset, jqAssets, fontsAsset;

    bootstrapCssAsset = getBootstrapCss();
    bootstrapJsAsset = getBootstrapJsScript();
    jqAssets = getBootstrapJqueryScript();
    fontsAsset = getBootstrapGlyphFonts();
    
    for (i = 0; i < bootstrapCssAsset.length; i += 1) {
        assetInfo = new AssetInfo(bootstrapCssAsset[i].fullPath, bootstrapCssAsset[i].file, bootstrapCssAsset[i].type, bootstrapCssAsset[i].useDefaultFolder, bootstrapCssAsset[i].documentRelative);
        assetList.push(assetInfo);
    }
    
    for (i = 0; i < bootstrapJsAsset.length; i += 1) {
        assetInfo = new AssetInfo(bootstrapJsAsset[i].fullPath, bootstrapJsAsset[i].file, bootstrapJsAsset[i].type, bootstrapJsAsset[i].useDefaultFolder, bootstrapJsAsset[i].documentRelative);
        assetList.push(assetInfo);
    }
    
    for (i = 0; i < jqAssets.length; i += 1) {
        assetInfo = new AssetInfo(jqAssets[i].fullPath, jqAssets[i].file, jqAssets[i].type, jqAssets[i].useDefaultFolder, jqAssets[i].documentRelative);
        assetList.push(assetInfo);
    }
    
    for (i = 0; i < fontsAsset.length; i += 1) {
        assetInfo = new AssetInfo(fontsAsset[i].fullPath, fontsAsset[i].file, fontsAsset[i].type, fontsAsset[i].useDefaultFolder, fontsAsset[i].documentRelative);
        assetList.push(assetInfo);
    }
    
    return assetList;
}

/*
 Is all set for HTML document creation?
	Called from NDD OnOK before proceeding with HTML document creation.
 This should validate inputs and handle creation/copy of bootstrap.css if neccessary.
 
 Returns:
	DW_NDD_CONSTANTS.BootstrapCreationInProgress - NDD should not handle OnOK and make itself busy mode.
	DW_NDD_CONSTANTS.AllValidationDone - NDD can go ahead and create document.
*/
function isAllSetForHTMLCreation() {
	"use strict";
	if (gBootstrapGeneratedPath) {
		return DW_NDD_CONSTANTS.AllValidationDone;
	}

	var retVal = DW_NDD_CONSTANTS.StopOnOKHandling,
		validUI = validateUI(),
		nddObj = dw.ndd;

	if (!validUI || !nddObj) {
		return retVal;
	}

	var uiOptions = getSelectedParameters();
	if (!uiOptions) {
		return retVal;
	}

	if (uiOptions.layoutType === DW_NDD_CONSTANTS.LayoutTypeNone) {
		retVal = DW_NDD_CONSTANTS.AllValidationDone;
	} else if (uiOptions.layoutType === DW_NDD_CONSTANTS.LayoutTypeBootstrap) {
		var curOptions = nddObj.getCurrentBootstrapOptions(),
			useExisting = false,
            useDefault = false,
			existingFile = "";

		if (uiOptions.breakPointsType === DW_NDD_CONSTANTS.UseExistingBootstrap) {
			if (curOptions.isSiteConfigured && !nddObj.isFileInsideSiteRoot(uiOptions.existingCSS)) {
				alert(getLocalString("Bootstrap_not_in_site"));
				return DW_NDD_CONSTANTS.StopOnOKHandling;
			}
			// No site setup, use CSS path as it is.
			existingFile = uiOptions.existingCSS;
			useExisting = true;
		} else if (isUIBootstrapUseDefaultSettings(uiOptions)) {
			var uri = dw.getUserConfigurationPath() + DW_NDD_CONSTANTS.BootstrapBundle + DW_NDD_CONSTANTS.BootstrapCss,
				searchUri = new DWUri(uri);

			useDefault = true;
			existingFile = searchUri.toLocalPath();
		}
       
		if ((useExisting || useDefault) && !DWfile.exists(existingFile)) {
			alert(getLocalString("Bootstrap_does_not_exist"));
			return DW_NDD_CONSTANTS.StopOnOKHandling;
		}
        
        //in case of 'use existing', as we have updated jquery version it might not be present in user's existing bootstrap location
        //So, if jquery-min.js file is not present, then copy it there
        if (useExisting && existingFile) {
            var existingFileUri = new DWUri();
            existingFileUri.localPathToURI(existingFile);
            var tempStr = "";
            tempStr += existingFileUri;
            var cssLastIndex = tempStr.lastIndexOf("/css");
            if (cssLastIndex !== -1) {
                var basePath = tempStr.substring(0, cssLastIndex);
                var destPath = basePath + DW_NDD_CONSTANTS.JQueryMinJS;
                if (!DWfile.exists(destPath)) {
                    var srcPath = dw.getUserConfigurationPath() + DW_NDD_CONSTANTS.BootstrapBundle + DW_NDD_CONSTANTS.JQueryMinJS;
                    if (DWfile.exists(srcPath)) {
                        nddObj.copyFile(srcPath, destPath);
                    }
                }
            }
        }

		// If site is configured
		if (curOptions.isSiteConfigured) {
			if (useExisting && nddObj.isFileInsideSiteRoot(existingFile)) {
				dWWriteLog("Choosed path already inside Site: " + existingFile);
				// Use this as the final CSS to embed in doc
				nddObj.setLastUsedBootstrapPath(existingFile);
				return DW_NDD_CONSTANTS.AllValidationDone;
			}
            
            if (useDefault && (curOptions.isBootstrapExists || DWfile.exists(curOptions.siteBootstrapPath))) {
                if (!confirm(getLocalString("Overwrite_site_bootstrap"))) {
                    return DW_NDD_CONSTANTS.StopOnOKHandling;
                }
            }

			// copy bootstrap bundle into site's root
			DWfile.remove(curOptions.siteBootstrapPath);
			copyBootstrapBundleIntoDir(curOptions.siteRoot);
			nddObj.setLastUsedBootstrapPath(curOptions.siteBootstrapPath);

			if (useExisting || useDefault) {
				return DW_NDD_CONSTANTS.AllValidationDone;
			}

			// Generate New bootstrap CSS 
			if (generateCSSFromNode(curOptions.siteBootstrapPath, uiOptions)) {
				return DW_NDD_CONSTANTS.BootstrapCreationInProgress;
			} else {
				callbackOnBootstrapError(gBootstrapGeneratedPath, "NODE SERVICE", "Failed to schedule generation of bootstrap.css");
				return DW_NDD_CONSTANTS.StopOnOKHandling;
			}
		} else { // case : No site is configured
            if (useDefault) {
                var assetList = getAssetListForDocCreation();
                nddObj.setAssetList(assetList);
            }
            
            if (useExisting || useDefault) {
                var lastUsedBSPath = existingFile;
                nddObj.setLastUsedBootstrapPath(lastUsedBSPath);
				return DW_NDD_CONSTANTS.AllValidationDone;
			}
        }

		var targetBootstapFolder = nddObj.getBootstrapFolderFromUser(),
			targetBootstapFile = targetBootstapFolder +  curOptions.pathSeparator + "css" + curOptions.pathSeparator + "bootstrap.css";

		// Copy all bootstrap files.
		copyBootstrapBundleIntoDir(targetBootstapFolder);

		// Generate New bootstrap CSS 
		if (generateCSSFromNode(targetBootstapFile, uiOptions)) {
			return DW_NDD_CONSTANTS.BootstrapCreationInProgress;
		} else {
			callbackOnBootstrapError(gBootstrapGeneratedPath, "NODE SERVICE", "Failed to schedule generation of bootstrap.css");
			return DW_NDD_CONSTANTS.StopOnOKHandling;
		}
	}
	return retVal;
}

/*
DW bridge API functions - Begin
*/

/*
Get dtd values to be populated in combobox
*/
function getDTDItems(argObj) {
    "use strict";
    var nddObj = dw.ndd;
    var dtdObj;
    if (nddObj) {
        dtdObj = nddObj.getDtdItemsArray();
        if (argObj && argObj.callback) {
            argObj.callback(dtdObj);
        }
    }
}

/*
When add CSS button is clicked from browser, this function is called which in turn calls the OnCssAddClick of NDD
*/
function onCssAddBtnClick(argObj) {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
		nddObj.onCssAddClick();
        if (argObj && argObj.callback) {
            argObj.callback();
        }
    }
}

/*
When remove CSS button is clicked from browser, this function is called which in turn calls the OnCssRemoveClick of NDD
*/
function onCssRemoveBtnClick(argObj) {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
		nddObj.onCssRemoveClick();
        if (argObj && argObj.callback) {
            argObj.callback();
        }
    }
}

/*
Function to get list of CSS filenames which have been added
*/
function getAttachCssListItems(argObj) {
    "use strict";
    var nddObj = dw.ndd;
    var attachCssListObj = [];
    if (nddObj) {
        attachCssListObj = nddObj.getAttachCssItemsArray();
        if (argObj && argObj.callback) {
            argObj.callback(attachCssListObj);
        }
    }
}

/*
Funciton to refresh the list with current list of css files
*/
function refreshAttachCssList() {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
        var attachCssListObj = nddObj.getAttachCssItemsArray();
        if (gNDDBrowserWin && gNDDBrowserWin.browserbridge) {
            gNDDBrowserWin.browserbridge.refreshAttachCssList(attachCssListObj);
        }
    }
}

/*
Function to pass list of CSS filenames selected to dw
*/
function onCssListSelect(selectedOptionsArray) {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
        var i, arr = [];
        for (i = 0; i < selectedOptionsArray.length; i++) {
            arr.push(selectedOptionsArray["" + i]);
        }
        nddObj.onCssListSelect(arr);
    }
}

function browseForFileURL(argObj) {
    'use strict';
    if (!argObj) {
        dWWriteLog("browseForFileURL :callback Obj not present");
        return;
    }

	var filter = [];
    filter[0] = argObj.filter;

	var path = "",
		uri = dw.browseForFileURL(argObj.operation, argObj.subOp, false, false, filter, "", true, "", "", true, true);

    if (uri) {
		var searchUri = new DWUri(uri);
		if (dw.ndd.isCurrentPlatformWin() === false) {
			// Hack for MAC. filter for forcing File Selection dialog 
			// to list "bootstrap*.css" is not working in MAC. This is to 
			// re-show the dialog, if user selects some other css.
			var	fileName = searchUri.getFilename();
			if (fileName.indexOf("bootstrap") !== 0) {
				setTimeout(function () {
					alert(getLocalString("Choose_bootstrap_css"));
					browseForFileURL(argObj);
				}, 100);
				return;
			}
		}
		path = searchUri.toLocalPath();
	}

    if (argObj.callback) {
        argObj.callback(path);
    }
}

/*
Function to open help url
*/
function openHelpPage(url) {
    "use strict";
    dw.openHelpURL(url);
}

/*
Function to set focus to a native control in ndd
*/
function setFocusToNddControl() {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
        nddObj.setFocusToNddContol();
    }
}

/*
Function to set focus to html subcategory in ndd
*/
function setFocusToHtmlSubCategory() {
    "use strict";
    var nddObj = dw.ndd;
    if (nddObj) {
        nddObj.setFocusToHtmlSubCategory();
    }
}

/*
Function to set focus to last control in browser
*/
function setFocusToLastControlInBrowser() {
    "use strict";
    if (gNDDBrowserWin && gNDDBrowserWin.browserbridge) {
		gNDDBrowserWin.browserbridge.setFocusToLastControlInBrowser();
	}
}

/** DW bridge API functions - END **/


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

		// Add all JS function interface in dwBridge object
		var dwBridge = {
			enableLog                               :   true,
            getDWDTDItems                           :   getDTDItems,
            onDWCssAddBtnClick                      :   onCssAddBtnClick,
            onDWCssRemoveBtnClick                   :   onCssRemoveBtnClick,
            getDWAttachCssListItems                 :   getAttachCssListItems,
			browseForFileURL						:	browseForFileURL,
            openDWHelpPage                          :   openHelpPage,
            configPath                              :   dw.getConfigurationPath(),
            onDWCssListSelect                       :   onCssListSelect,
            setFocusToNddControl                    :   setFocusToNddControl,
            setFocusToHtmlSubCategory               :   setFocusToHtmlSubCategory
		};

		var curNddOptions,
			nddObj = dw.ndd;
		if (nddObj) {
			curNddOptions = nddObj.getCurrentBootstrapOptions();
			curNddOptions.isWinOS = nddObj.isCurrentPlatformWin();

            nddObj.setDwBrowserForNDD(gNDDBrowserCtrl);
		}

		// Initialize Bridge
		gNDDBrowserWin.browserbridge.initialize(dwBridge, curNddOptions, window.innerHeight - 4, window.innerWidth - 10);
        gNDDBrowserCtrl.style.display = "block";
	} catch (exception) {
		dWWriteLog("<NDD initialization> EXCEPTION: Brower loading failed");
    }
}

//Initialize the view and load webview
function initializeUI() {
	"use strict";
    if (gIsNDDInited === false) {
        gNDDBrowserCtrl = document.getElementById("browser_ndd");
        gNDDBrowserCtrl.addEventListener("BrowserControlLoad", browserControlLoaded, true);

		var url = dw.getConfigurationPath() + DW_NDD_CONSTANTS.BrowserMainURL;
        gNDDBrowserCtrl.openURL(url);

        gIsNDDInited = true;
    }
}

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

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

    if (gNDDBrowserCtrl && gNDDBrowserCtrl.style) {
        gNDDBrowserCtrl.style.height = (window.innerHeight - 4) + "px";
        gNDDBrowserCtrl.style.width  = (window.innerWidth - 10) + "px";
    }
}
