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

Purpose- 
This file contains all the logic to identify the framework and set up appropriate variables
*/

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, maxerr: 50, continue: true */
/*global ResponsiveLayoutConstants, DebugUtils, $dwJQuery, unloadResponsiveLayoutExtension, CSSRule, RESPONSIVE_FRAMEWORK */

/* AdobePatentID="P5361-US". */

var ResponsiveFrameworkLookup = {
    
    frameworkXML: [], // initially an array of all frameworks supported. replaced with the document object for the identified framework for the loaded html.
    frameworkCSS: "",

    /*
        function:isSupportedFrameworkCSS() - Returns true if the stylesheet object is created from a supported framework as defined in xml
        Arguments: stylesheet object, out parameter to set the responsive framework
        Return: bool
    */
    isSupportedFrameworkCSS: function (styleSheet) {
        "use strict";
        // temporary way to identify a responsive framework
        var i = 0,
            supportedVersion = -1,
            curStyleSheet = styleSheet;
        DebugUtils.log("Fn - isSupportedFrameworkCSS for: " + styleSheet.href);
        for (i = 0; i < this.frameworkXML.length; i++) {
            var frameworkElements = this.frameworkXML[i].getElementsByTagName(ResponsiveLayoutConstants.DESCRIPTORS.FRAMEWORK_NAME);
            if (frameworkElements && frameworkElements.length === 1) {
                var frameworkName = frameworkElements[0].textContent.toLowerCase();
                if (frameworkName) {
                    var filename = styleSheet.href;
                    if (!filename) {
                        // if it is an import rule check for the embedded stylesheet
                        if (styleSheet.cssRules
                                && styleSheet.cssRules.length === 1
                                && styleSheet.cssRules[0].type === CSSRule.IMPORT_RULE
                                && styleSheet.cssRules[0].href) {
                            curStyleSheet = styleSheet.cssRules[0].styleSheet;
                            filename = styleSheet.cssRules[0].href;
                        }
                    }
                    if (filename) {
                        var fileLocationArr = filename.split("/");
                        filename = fileLocationArr[fileLocationArr.length - 1];
                    }
                    if (filename && filename.toLowerCase().search(frameworkName) !== -1) {
                        this.lookUpFrameworkCSS(curStyleSheet, i, frameworkName);
                        return true;
                    }
                }
            } else {
                DebugUtils.logError("XML should be validated by the schema properly.");
                DebugUtils.assert(false);
            }
        }
        
        return false;
    },
    
    frameworkCSSLoadingComplete: function (xmlIndex, frameworkName, loadExtension) {
        "use strict";
        
        if (typeof this.frameworkXML.length === "undefined" || xmlIndex < 0 || xmlIndex >= this.frameworkXML.length) {
            this.resetDocumentAndUnloadExtension();
            return;
        }
        if (loadExtension) {
            var supportedVersion = this.lookForFrameworkVersion(xmlIndex);
            if (supportedVersion !== -1) {
                // populate with the identified data
                ResponsiveLayoutConstants.docWindowObj.responsiveInfo.frameworkVersion = supportedVersion;
                ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework = frameworkName;
                // select the frameworkXML detected and free the remaining
                this.frameworkXML = this.frameworkXML[xmlIndex];
                ResponsiveLayoutConstants.docWindowObj.liveViewExtensionsObject.loadExtensionById(ResponsiveLayoutConstants.ExtensionId, true);
                ResponsiveLayoutConstants.docWindowObj.liveViewExtensionsObject.showExtensionById(ResponsiveLayoutConstants.ExtensionId);
            }
        } else {
            ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework = frameworkName;
            this.frameworkXML = this.frameworkXML[xmlIndex];
        }
    },

    /*
        function:lookUpFrameworkCSS() - fetch and store the framework css for future use. If loading fails feature will fail - unload the extension
        Arguments: styleSheet object to be loaded
        Return: nothing.
    */
    lookUpFrameworkCSS: function (styleSheet, xmlIndex, frameworkName) {
        "use strict";
        
        if (typeof ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework !== "undefined"
                && ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework
                && ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework === frameworkName
                && typeof ResponsiveLayoutConstants.docWindowObj.responsiveInfo.frameworkHREF !== "undefined"
                && ResponsiveLayoutConstants.docWindowObj.responsiveInfo.frameworkHREF
                && ResponsiveLayoutConstants.docWindowObj.responsiveInfo.frameworkHREF === styleSheet.href) {
            // The proper framework is already loaded
            this.frameworkCSSLoadingComplete(xmlIndex, frameworkName, false);
            return;
        } else {
            // unload the extension since it seems to be loaded for a different framework
            this.resetDocumentAndUnloadExtension();
        }
        var loadCompleted = function (result) {
            ResponsiveFrameworkLookup.frameworkCSS = result;
            ResponsiveLayoutConstants.docWindowObj.responsiveInfo.frameworkHREF = styleSheet.href;
            ResponsiveFrameworkLookup.frameworkCSSLoadingComplete(xmlIndex, frameworkName, true);
        },
            loadError = function (result) {
                DebugUtils.assert(false);
                DebugUtils.logError("failed to load CSS file from path: " + styleSheet.href);
            };
        
        if ((styleSheet.href.indexOf("file://") === 0) && ((window.location.href.indexOf("http://") === 0) || (window.location.href.indexOf("https://") === 0))) {
            var callbackFunction = function (resultObj) {
                    if (resultObj && resultObj.fileStr) {
                        loadCompleted(resultObj.fileStr);
                    } else {
                        loadError();
                    }
                };
            ResponsiveLayoutConstants.docWindowObj.liveViewExtensionsObject.dwObject.readFile(styleSheet.href, callbackFunction);
        } else {
            // load the css file synchronously
            $dwJQuery.ajax({
                'url': styleSheet.href,
                'data': 'string',
                'success': loadCompleted,
                'error': loadError,
                'dataType': 'text'
            });
        }
    },

    /*
        function:lookForFrameworkVersion() - Returns the version num if the document has a version attached that is supported within our Responsive Tooling set
        Arguments: xmlIndex: Number
        Return: boolean.
    */
    lookForFrameworkVersion: function (xmlIndex) {
        "use strict";
        if (ResponsiveFrameworkLookup.frameworkCSS !== "") {
            var frameworkVersionRegex = ResponsiveFrameworkLookup.frameworkXML[xmlIndex].getElementsByTagName(ResponsiveLayoutConstants.DESCRIPTORS.FRAMEWORK_VERSION);
            if (frameworkVersionRegex.length > 0) {
                frameworkVersionRegex = frameworkVersionRegex[0].textContent;
                var versionRegex = new RegExp(frameworkVersionRegex, "i"),
                    versionNum = ResponsiveFrameworkLookup.frameworkCSS.match(versionRegex);
                if (versionNum && versionNum.length === 2) {
                    return versionNum[1];
                }
            }
        }
        return -1;
    },

    resetDocumentAndUnloadExtension: function () {
        "use strict";
        // ensure responsive info is reset
        ResponsiveLayoutConstants.docWindowObj.responsiveInfo = {};
        ResponsiveLayoutConstants.docWindowObj.liveViewExtensionsObject.dwObject.setResponsiveFeatures("", [], true);
        // attempt unloading. Will be a no-op if not present.
        window.liveViewExtensionsObject.unloadExtensionById(RESPONSIVE_FRAMEWORK.ExtensionId);
    },
    
    /*
        function:lookForResponsiveFrameworkCSS() - Iterate over all stylesheet to see if there is a framework we recognize
        Arguments: none
        Return: None.
    */
    lookForResponsiveFrameworkCSS: function () {
        "use strict";
        var i = 0,
            docStyleSheets = ResponsiveLayoutConstants.docWindowObj.document.styleSheets;
        if (docStyleSheets.length > 0) {
            for (i = 0; i < docStyleSheets.length; i++) {
                // Assuming there will only be one supported framework attached in a document.
                // Multiple Frameworks does not make sense
                if (this.isSupportedFrameworkCSS(docStyleSheets[i])) {
                    return;
                }
            }
            
            DebugUtils.log("No Responsive Framework found - unload extension!!!");
            // No Responsive Framework Found
            this.resetDocumentAndUnloadExtension();
        }
    },
    
    isBootstrapResponsiveFrameworkLoaded: function () {
        "use strict";
        return (ResponsiveLayoutConstants.docWindowObj.responsiveInfo.responsiveFramework === ResponsiveLayoutConstants.FRAMEWORK.BOOTSTRAP);
    }
};