/*
   Copyright 2015 Adobe Systems Incorporated.  All rights reserved.
*/
/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, maxerr: 50 */
/*global document, dw, NODEOUTPUTPREVIEW_CONSTANTS*/

var nodeOutputPreviewObj = (function () {
    "use strict";
	var strHtmlContentToLoad = "";
	var configPath = dw.getConfigurationPath();
	var isTemplateReady = false;
	var pxNodeOutputBrowserControlWidth = (NODEOUTPUTPREVIEW_CONSTANTS.NodeOutput_Preview_Width + NODEOUTPUTPREVIEW_CONSTANTS.NodeOutput_Preview_Padding).toString() + 'px';
	var pxNodeOutputBrowserControlHeight = (NODEOUTPUTPREVIEW_CONSTANTS.NodeOutput_Preview_Height + NODEOUTPUTPREVIEW_CONSTANTS.NodeOutput_Preview_Padding);
    var strWidth = 0;
    var strHeight = 0;
	
	return {
        //Getter and setter functions for some variables used outside this context
        getIsTemplateReady: function () {
            return isTemplateReady;
        },
        
        getstrHtmlContentToLoad: function () {
            return strHtmlContentToLoad;
        },
        
        resetstrHtmlContentToLoad: function () {
            strHtmlContentToLoad = "";
			isTemplateReady = false;
        },
        
	    //error str can have html tags and hence escape them
        parseHTMLTags: function (errorStr) {
            var updatedStr = errorStr;
            updatedStr = updatedStr.replace("<", "&lt;");
            updatedStr = updatedStr.replace(">", "&gt;");
            return updatedStr;
        },

        resetValues: function () {
            strWidth = 0;
            strHeight = 0;
        },
        
        //trim sometimes doesn't work on SM layer , so implementing own trim to trim out the leading and trailing white spaces
        localTrim: function (value) {
            if ((typeof value === 'string') && value.length > 0) {
                return value.replace(/^\s+|\s+$/gm, '');
            } else {
                return value;
            }
        },
	
	   //Generate the html which needs to be loaded ( i.e, browser control)
        generateTemplateHtml: function (arrErrorObj, strCodeViewTheme) {
            if (arrErrorObj === undefined || !(arrErrorObj instanceof Object) || arrErrorObj.length === 0 || strCodeViewTheme === undefined) {
                return;
            }
            var strThemeCSSClass = (nodeOutputPreviewObj.localTrim(strCodeViewTheme.toLocaleLowerCase()) === 'white') ? 'light' : 'dark';

            var anError = arrErrorObj[0];
            if (anError && ("isError" in anError) && ("resultText" in anError)) {
                var isError = arrErrorObj[0].isError;
                var strError = nodeOutputPreviewObj.parseHTMLTags(arrErrorObj[0].resultText);

                var iconDiv = "errorIconDiv";
                if (!isError) {
                    iconDiv = "warningIconDiv";
                }
                strHtmlContentToLoad = '<!doctype html><html><head><meta charset="utf-8"><title></title><link rel="stylesheet" type="text/css" href="' + configPath + NODEOUTPUTPREVIEW_CONSTANTS.Preview_Styles_File_Path + '" /><script>function HandleMouseEntered() {  window.MouseEntered(); }</script></head><body  onmouseenter="HandleMouseEntered()" class="' + strThemeCSSClass + 'Theme"><span id="contentspan" style="white-space:nowrap; display:inline-block"><div class="' + iconDiv + '"></div>' + strError + '</span></body></html>';
                isTemplateReady = true;
            }
        },
	
        //set the browser control size which should be the same width as the rendered string
        generateBrowserControlSize: function (width, height) {
            
            if (strWidth !== undefined && strHeight !== undefined) {
                if (width > 0  && height === 0) {
                    strWidth = width;
                    strHeight = pxNodeOutputBrowserControlHeight;
                }
                

                if (strWidth > 0 && strHeight > 0) {

                    var retValForValidPreview;
                    var brsCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);
                    if (brsCtrl !== undefined) {
                        var paddingAcrossCanvas = 28; //5 px for padding on all sides and 1px for border across
                        var browserControlWidth = (strWidth + paddingAcrossCanvas).toString() + 'px';
                        var browserControlHeight = strHeight.toString() + 'px';
                        brsCtrl.style.width = browserControlWidth;
                        brsCtrl.style.height = browserControlHeight;
                        if (brsCtrl.parentNode !== undefined) {
                            brsCtrl.parentNode.style.width = browserControlWidth;
                            brsCtrl.parentNode.style.height = browserControlHeight;
                        }


                        retValForValidPreview = {
                            CanHandle : NODEOUTPUTPREVIEW_CONSTANTS.Can_I_Handle_The_Trigger.WillHandleNow,
                            HighLight : NODEOUTPUTPREVIEW_CONSTANTS.Highlight_Code.No,
                            PreviewMode : NODEOUTPUTPREVIEW_CONSTANTS.Preview_Mode,
                            Start : 0,
                            End : 0,
                            Width :  browserControlWidth,
                            Height : browserControlHeight
                        };

                        dw.setAssetPreviewParameters(retValForValidPreview);
                    }

                } else if (strWidth === 0 && strHeight === 0) {
                    var retValForInvalidPreview;
                    var browserCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);
                    if (browserCtrl !== undefined) {
                        var browserCtrlWidth = pxNodeOutputBrowserControlWidth;
                        var browserCtrlHeight = pxNodeOutputBrowserControlHeight.toString() + 'px';
                        browserCtrl.style.width = browserCtrlWidth;
                        browserCtrl.style.height = browserCtrlHeight;
                        if (browserCtrl.parentNode !== undefined) {
                            browserCtrl.parentNode.style.width = browserCtrlWidth;
                            browserCtrl.parentNode.style.height = browserCtrlHeight;
                        }

                        retValForInvalidPreview = {
                            CanHandle : NODEOUTPUTPREVIEW_CONSTANTS.Can_I_Handle_The_Trigger.WillHandleNow,
                            HighLight : NODEOUTPUTPREVIEW_CONSTANTS.Highlight_Code.No,
                            PreviewMode : NODEOUTPUTPREVIEW_CONSTANTS.Preview_Mode,
                            Start : 0,
                            End : 0,
                            Width :  browserCtrlWidth,
                            Height : browserCtrlHeight
                        };


                        dw.setAssetPreviewParameters(retValForInvalidPreview);
                    }
                    nodeOutputPreviewObj.resetValues();
                }
            }
        }
	};
}());

function smMouseEntered()
{
	 "use strict";
     dw.hidePreviewOnMouseEnteredWindow();
}


//Reset the HTML Content to be previewed once it is loaded
function browserControlLoaded() {
    "use strict";

    var objBrowserCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);

    if (objBrowserCtrl !== undefined) {
        var browserWin = objBrowserCtrl.getWindow();
        if (browserWin) {
            browserWin.MouseEntered = smMouseEntered;
		}
        objBrowserCtrl.removeEventListener("BrowserControlLoad", browserControlLoaded, true);
        if (nodeOutputPreviewObj.getstrHtmlContentToLoad() !== undefined) {
            nodeOutputPreviewObj.resetstrHtmlContentToLoad();
        }
    }
}

/* Preview onresize function to load the HTML to be previewed */
function loadHTMLContent() {
	"use strict";

	var objBrowserCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);

	//If the template HTML is ready for preview, load it
	if (nodeOutputPreviewObj.getIsTemplateReady() === true) {
		if (objBrowserCtrl !== undefined && nodeOutputPreviewObj.getstrHtmlContentToLoad() !== undefined) {
			//Register event listener to Browser Control to reset the Preview content once it is loaded
			objBrowserCtrl.addEventListener("BrowserControlLoad", browserControlLoaded, true);
			//Load the HTML to be previewed
			objBrowserCtrl.loadHTML(nodeOutputPreviewObj.getstrHtmlContentToLoad());
		}
	} else if (objBrowserCtrl !== undefined) {
		objBrowserCtrl.loadHTML(NODEOUTPUTPREVIEW_CONSTANTS.Blank_HTML);
	}
}



//get the span width which will be width of the string and image being shown
function browserControlForDraftHTMLLoaded() {
    "use strict";
    try {
        var brsCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);
        brsCtrl.removeEventListener("BrowserControlLoad", browserControlForDraftHTMLLoaded, true);
        var browserWin = brsCtrl.getWindow();

        if (browserWin) {
			
			var spanElem = browserWin.document.getElementById("contentspan");
			if (spanElem) {
				
				var strWidth = spanElem.offsetWidth;
				var strHeight = 0;
				nodeOutputPreviewObj.generateBrowserControlSize(strWidth, strHeight);
				
			}
		}
	} catch (exception) {
        //alert(exception);
    }
}

/* Dreamweaver extension API : this will be called from Dreamweaver
    ShowErrorPreview : client is supposed to parse the arrObj which has the errors/warnings and return back a DocView if it wants to handle it , otherwise null
    param: docType type of the currently active document opened in code view	
	param: arrObj nodeoutput errors/warnings for the current line no when the mouse is on line no column
    param: colorTheme current color theme ( Dark / Light)
 */
function ShowErrorPreview(strDocumentType, arrErrorObj, strCodeViewTheme) {
	"use strict";
	
	nodeOutputPreviewObj.resetValues();
	var canIHandleTheHover = NODEOUTPUTPREVIEW_CONSTANTS.Can_I_Handle_The_Trigger.WillHandleLater;
		
	if (strDocumentType !== undefined && arrErrorObj !== undefined && strCodeViewTheme !== undefined) {
		//Generate the HTML to be loaded when we have a error to be shown on mouse hover on line no column
		nodeOutputPreviewObj.generateTemplateHtml(arrErrorObj, strCodeViewTheme.toString());
		var objBrowserCtrl = document.getElementById(NODEOUTPUTPREVIEW_CONSTANTS.Browser_Control);
		if (nodeOutputPreviewObj.getIsTemplateReady()) {
			if (objBrowserCtrl !== undefined) {
				objBrowserCtrl.setScrollbarMode("off", "h");
				objBrowserCtrl.setScrollbarMode("off", "v");
			    objBrowserCtrl.addEventListener("BrowserControlLoad", browserControlForDraftHTMLLoaded, true);
                objBrowserCtrl.loadHTML(nodeOutputPreviewObj.getstrHtmlContentToLoad());
			}
		}
	}
	//first we have to render to find the text's actual width which we set on the browser control in the subsequent loadhtml and
	//hence return canhandle as willhandlelater
	var retVal = {CanHandle : canIHandleTheHover};
	return retVal;
}