var HelloPhotoshop = function ()
{
    /**
     * Private debug flag for this object container.
     */
    var debugMode = true;
    
    /**
     * Content URL's for the point product.
     */
    this.url =
    {
        online  : "https://helpx.qa.adobe.com/photoshop/hello/v1_5/index.html",
        offline : "./offline/index.html"
    }
    
    /**
     * All the point products seem to have implemented a different event types, so we need this
     * definition here until we can standardize them.
     */
    this.events =   {
        pipEventType                    : "com.adobe.PhotoshopLOGPIP",
        aboutToCloseEvent               : "com.adobe.photoshop.welcome.aboutToAutomaticallyCloseHello",
        handleExecuteMenuCommand        : (void 0),
        handleRecentFileOpen            : "com.adobe.photoshop.welcome.HandleRecentFileOpen",
        contentTabChangedNotification   : "com.adobe.photoshop.welcome.contentTabChangedNotification",
        isInContentTutorialNotification : "com.adobe.photoshop.welcome.isInContentTutorialNotification"
    }
    
    /**
     * UI element definitions.
     */
    this.ui     =   {
        create  :   {
            initialImage    : "images/PSCreateInitialExp.jpg",
            backgroundColor : "#000000"
        },
        footer  :   {
            helpURL         : "https://helpx.adobe.com/photoshop.html",
            helpLabel       : "Photoshop Help",
            forumsURL       : "https://forums.adobe.com/community/photoshop",
            forumsLabel     : "Forums",
            inspireURL      : "https://www.behance.net/search?sort=featured_date&user_tags=971223",
            inspireLabel    : "Inspire",
            blogURL         : "http://blogs.adobe.com/photoshopdotcom",
            blogLabel       : "Blog"
        }
    }
    
    /**
     * Workaround for now since all the point products seem to have implemented a different PIP data format.
     */
    this.useJSONPIPData = false;
    
    /**
     * Another workaround for merging the different PP extensions into one. Although we have
     * a different extension ID, the host app expects the following one in order for it's
     * various pieces to work correctly.
     */
    this.overrideExtensionID = "com.photoshop.Welcome.extension1";
    
    /**
     *
     */
    var docSetup = {};
    
	docSetup.default =     { width: 504,
    height: 360,
    name: 'Default Photoshop Size',
    resolution: 300,
        profile: undefined };
	docSetup.print =       { width: 612,
    height: 792,
    name: 'Print Document',
    resolution: 300,
        profile: undefined };
	docSetup.photo =       { width: 360,
    height: 504,
    name: 'Photo Document',
    resolution: 300,
        profile: undefined };
	docSetup.web =         { width: 691.2,
    height: 388.8,
    name: 'Web Document',
    resolution: 200,
        profile: undefined };
	docSetup.mobile =      { width: 141.3497,
    height: 250.8957,
    name: 'Mobile App Design Document',
    resolution: 326,
        profile: 'sRGB IEC61966-2.1' };
    docSetup.iconography = { width: 26.503,
    height: 26.503,
    name: 'Iconography Document',
    resolution: 326,
        profile: 'sRGB IEC61966-2.1' };
	docSetup.film =        { width: 504,
    height: 360,
    name: 'Film & Video Document',
    resolution: 300,
        profile: 'sRGB IEC61966-2.1' };
	docSetup.preset =      { width: undefined,
    height: undefined,
    name: 'Document From Saved Preset',
    resolution: undefined,
        profile: undefined };
	docSetup.custom =      { width: undefined,
    height: undefined,
    name: 'Custom Document',
    resolution: undefined,
        profile: undefined };
    
    /**
     * Get the Hello JSON data corresponding to the currently logged in user.
     *
     * @param callback      function object which will be called on data generation completion
     */
    HelloPhotoshop.prototype.getUserJsonData = function( callback )
    {
        try
        {

            if ( ! debugMode )
            {
                alert("foo:"+window.__adobe_hello.isWindowsOS());
//                window.__adobe_hello.evalScript( "fuction() { var iswin = IsWindowsOS(); return iswin; } ();", function(jsonData) { alert("back: "+jsonData); } );
//                window.__adobe_hello.evalScript( "GetJSONData()", callback );
            }
            else
            {
                var jsData = window.__adobe_hello.getDebugJSON();
                
                if( callback != null && (typeof callback !== "undefined") )
                {
                    callback( jsData );
                }
            }
        }
        catch( e )
        {
            window.__adobe_hello.logMessage( "HelloPhotoshop.getUserJsonData catch: " + e.message );
        }
    }
    
    /**
     * Opens an existing document.  If the specified path is the constant string
     * "open" then it will open the browse/open file UI in the host application.
     *
     * @param fullPath      string object containing the path or ID of the existing
     *                      document to open
     */
    HelloPhotoshop.prototype.openExistingDocument = function( fullPath )
    {
        if ( fullPath == "open" )
        {
            var result = window.cep.fs.showOpenDialog();
            
            if ( result && result.data.length)
            {
                var temp = result.data[0];
                
                if ( window.__adobe_hello.isWindowsOS() )
                {
                    fullPath = '/' + temp[0] + temp.substr(2, temp.length);
                }
                else
                {
                    fullPath = temp;
                }
            }
            else
            {
                fullPath = (void 0);
            }
        }
        
        if ( typeof fullPath !== "undefined" )
        {
            /**
             * callback for evalScript
             */
            var localAppOpen = function( result )
            {
                window.__adobe_hello.sendaboutToCloseEvents();
                window.__adobe_hello.closeHello();
            }
            // FIXME -razvan request refactor "	what if fullPath has a " in it?"
            window.__adobe_hello.evalScript( 'try { if (File("' + fullPath + '").exists) { var a = app.open(File("' + fullPath + '")); } } catch(e) { alert(e + ":" + e.line); }', localAppOpen );
            window.__adobe_hello.logHelloInteractionPIPEvent( "OpenExistingDoc" );
        }
    }
    
    /**
     * document setup for openDocumentOfType
     */
    var generateScriptForNewDoc = function( inObj, inPreset )
    {
        var script = "try { returnResult = '" + inPreset + "';";
        
        if (inPreset === "preset" || inPreset === "custom")
        {
            script += "app.displayDialogs = DialogModes.ALL;";
        }
        else
        {
            script += "app.displayDialogs = DialogModes.NO;";
        }
        var obj = inObj[inPreset];
        script += 'idMk = charIDToTypeID( "Mk  " );';
        script += 'desc1 = new ActionDescriptor();';
        script += 'idNw = charIDToTypeID( "Nw  " );';
        script += 'desc2 = new ActionDescriptor();';
        script += 'idNm = charIDToTypeID( "Nm  " );';
        script += 'desc2.putString( idNm, "' + obj.name + '");';
        script += 'idMd = charIDToTypeID( "Md  " );';
        script += 'idRGBM = charIDToTypeID( "RGBM" );';
        script += 'desc2.putClass( idMd, idRGBM );';
        script += 'unitPixels = charIDToTypeID( "#Pxl" );';
        script += 'idWdth = charIDToTypeID( "Wdth" );';
        if (typeof obj.width !== undefined)
        {
            script += 'desc2.putUnitDouble( idWdth, unitPixels, ' + obj.width + ');';
        }
        script += 'idHght = charIDToTypeID( "Hght" );';
        if (typeof obj.height !== undefined)
        {
            script += 'desc2.putUnitDouble( idHght, unitPixels, ' + obj.height + ');';
        }
        script += 'idRslt = charIDToTypeID( "Rslt" );';
        if (typeof obj.resolution !== undefined)
        {
            script += 'desc2.putUnitDouble( idRslt, unitPixels, ' + obj.resolution + ');';
        }
        script += 'idpixelScaleFactor = stringIDToTypeID( "pixelScaleFactor" );';
        script += 'desc2.putDouble( idpixelScaleFactor, 1.000000 );';
        script += 'idFl = charIDToTypeID( "Fl  " );';
        script += 'idWht = charIDToTypeID( "Wht " );';
        script += 'desc2.putEnumerated( idFl, idFl, idWht );';
        script += 'idDpth = charIDToTypeID( "Dpth" );';
        script += 'desc2.putInteger( idDpth, 8 );';
        if (typeof obj.profile !== undefined)
        {
            script += 'idprofile = stringIDToTypeID( "profile" );';
            script += 'desc2.putString( idprofile, "' + obj.profile + '");';
        }
        script += 'idDcmn = charIDToTypeID( "Dcmn" );';
        script += 'desc1.putObject( idNw, idDcmn, desc2 );';
        script += 'resultDesc = executeAction( idMk, desc1, app.displayDialogs );';
        script += 'if (app.displayDialogs == DialogModes.ALL && resultDesc.count && resultDesc.hasKey( idNw )) {';
        script += '     objDesc = resultDesc.getObjectValue( idNw );';
        script += '     idpreset = stringIDToTypeID( "preset" );';
        script += '     if (objDesc.count && objDesc.hasKey( idpreset )) {';
        script += '          returnResult = objDesc.getString( idpreset );';
        script += '     }';
        script += '     if (objDesc.count && objDesc.hasKey( idWdth ) && objDesc.hasKey( idHght ) && objDesc.hasKey( idRslt )) {';
        script += '          returnResult = objDesc.getUnitDoubleValue( idWdth );';
        script += '          returnResult += "x" + objDesc.getUnitDoubleValue( idHght );';
        script += '          returnResult += "x" + objDesc.getUnitDoubleValue( idRslt );';
        script += '     }';
        script += '}';
        script += "returnResult; } catch(e) { 'ERROR'; }";
        return script;
    }
    
    /**
     * Create a new document of the specified type by showing the appropriate new document
     * UI.  If the 'suppressNewDocUI' is true then the document created with default params
     * and the new document UI is not shown.
     *
     * @param documentType          string object containing the ID of the new doc type to
     *                              create
     * @param suppressNewDocUI      boolean value indicating true to not show the new doc UI,
     *                              false otherwise
     */
    HelloPhotoshop.prototype.openDocumentOfType = function( documentType, suppressNewDocUI )
    {
        var script = this.generateScriptForNewDoc( docSetup, documentType );
        
        /**
         * callback for evalScript
         */
        var newDocResult = function( inResult )
        {
            window.__adobe_hello.logHelloInteractionPIPEvent( "CreateNewDoc:" + inResult );
            window.__adobe_hello.sendAboutToCloseEvents();
            window.__adobe_hello.closeHello();
        }
        
        window.__adobe_hello.evalScript( script, newDocResult );
    }
    
    /**
     * Sets the "Don't Show Again" preference in the host application.
     *
     * @param dontShowAgain     boolean value indicating true if "dont show again" was
     *                          requested, false otherwise
     */
    HelloPhotoshop.prototype.setDontShowAgainPreference = function( dontShowAgain )
    {
        window.__adobe_hello.logHelloInteractionPIPEvent( (( dontShowAgain ) ? "SetDoNotShowAgain" : "ClearDoNotShowAgain") );

        var trueOrFalse = dontShowAgain ? "true" : "false";
        var script      = "SetDontShowAgain(" + trueOrFalse + ");";
        
        window.__adobe_hello.evalScript( script );
    }
    
    /**
     * Attempt to reload the Hello URL from the server.
     */
    HelloPhotoshop.prototype.retryLoadFromServer = function()
    {
    	window.__adobe_hello.logHelloInteractionPIPEvent( "RetryPageLoad" );

        if (window.navigator.onLine === true)
        {
            window.location = window.__adobe_hello.getHelloURL();
        }
    }
    
    /**
     * Auto-close the Hello UI interface.
     */
    HelloPhotoshop.prototype.notifyDoneWithDialog = function()
    {
        if ( window.__adobe_cep__ )
        {
            window.__adobe_hello.logHelloInteractionPIPEvent( "DialogAutoDismiss" );
            window.__adobe_cep__.closeExtension();
        }
    }
    
    /**
     * Indicate that the requested URL failed to load.
     *
     * @param errorString       string object containing the error description
     */
    HelloPhotoshop.prototype.notifyFailedToLoad = function( errorString )
    {
        if ( errorString )
            window.__adobe_hello.logPIPEvent( "ProjectHello", "Failure", errorString );
    }
    
    /**
     * Send a notification message to the host application indicating the content has entered
     * a tutorial.
     *
     * @param isInContentTutorial   boolean value indicating true if content is tutorial, false otherwise
     */
    HelloPhotoshop.prototype.notifyInContentTutorial = function( isInContentTutorial )
    {
        window.__adobe_hello.sendEvent( this.events.isInContentTutorialNotification, (isInContentTutorial ? "Yes" : "No"));
    }
    
    /**
     * Send a notification message to the host application indicating the conent tab has changed.
     *
     * @param currentTab        string object containing the current tab's ID
     */
    HelloPhotoshop.prototype.notifyContentTabChanged = function( currentTab )
    {
        window.__adobe_hello.sendEvent( this.events.contentTabChangedNotification, currentTab);
    }
};

function GetJSONData()
{
    alert("foo");
    
    var welcomeInfo = GetWelcomeInfo();
    // Coerce other english varients to en_US
    var modLocale = app.locale;
    if (! (modLocale in {"en_US":1, "en_GB":1}))
    {
        if (modLocale.match(/en_??/))
            modLocale = "en_US";
    }
    var a = '{"appid":"1235",';
    a += '"appversion":"' + app.version + '",';
    a += '"platform":"' + (IsWindowsOS() ? "win" : "mac") + '",';
    a += '"language":"' + modLocale + '",';
    a += '"userTrackingEnabled":"' + welcomeInfo.userTrackingEnabled + '",';
    a += '"adobeid":"' + GetAdobeID() + '",';
    a += '"greeting":"' + welcomeInfo.greeting + '",';
    a += '"countryCode":"' + welcomeInfo.countryCode + '",';
    a += '"delegateGuid":"' + GetDelegateGUID() + '",';
    a += '"accountType":"' + welcomeInfo.accountType + '",';
    a += '"secondsLeftInTrial":"' + welcomeInfo.secondsLeftInTrial + '",';
    a += '"appStartClockTime":"' + welcomeInfo.appStartClockTime + '",';
    a += '"newDocTypes":[' + GetNewDocTypes() + '],';
    a += '"recentFiles":[' + GetRecentFiles() + '],';
    a += '"dontShowAgain":"' + GetDontShowAgain().toString() + '",';
    a += '"lastError":"' + welcomeInfo.lastError + '"}';
    return a;
}

function GetWelcomeInfo()
{
    try {
        var w = {};
        w.userTrackingEnabled = true;
        w.greeting = "Hello!";
        w.accountType = "trial";
        w.secondsLeftInTrial = "1396292060";
        w.appStartClockTime =  "1396292061";
        w.lastError = "";
        w.countryCode = "US";
        var classApplication   = charIDToTypeID('capp');
        var typeOrdinal        = charIDToTypeID('Ordn');
        var enumTarget         = charIDToTypeID('Trgt');
        var welcome            = charIDToTypeID('wlcm');
        var classProperty      = charIDToTypeID("Prpr");
        var kentryStatusStr    = stringIDToTypeID("entryStatus");
        var kleftStr           = stringIDToTypeID("left");
        var kstartTimeStr      = stringIDToTypeID("startTime");
        var koptinStr          = stringIDToTypeID("optin");
        var kfirstStr          = stringIDToTypeID("first");
        var kisoCountryCodeStr = stringIDToTypeID("isoCountryCode");
        var ref = new ActionReference();
        ref.putProperty(classProperty, welcome);
        ref.putEnumerated(classApplication, typeOrdinal, enumTarget);
        var appDesc = app.executeActionGet(ref);
        if (appDesc.hasKey(welcome)) {
            welcomeDesc = appDesc.getObjectValue(welcome);
            if (welcomeDesc.count) {
                w.accountType = welcomeDesc.getInteger(kentryStatusStr) == 1 ? "trial" : "paid";
                w.secondsLeftInTrial = welcomeDesc.getLargeInteger(kleftStr);
                w.appStartClockTime = welcomeDesc.getLargeInteger(kstartTimeStr);
                w.userTrackingEnabled = welcomeDesc.getBoolean(koptinStr);
                w.greeting = "Hello, " + welcomeDesc.getString(kfirstStr) + "!";
                w.countryCode = welcomeDesc.getString(kisoCountryCodeStr);
            }
        }
    }
    catch(e) {
        ;
    }
    return w;
}

function GetDelegateGUID()
{
    var s = "ERROR GUID";
    try {
        var classApplication = charIDToTypeID('capp');
        var typeOrdinal      = charIDToTypeID('Ordn');
        var enumTarget       = charIDToTypeID('Trgt');
        var behance          = charIDToTypeID('bhnc');
        var classProperty    = charIDToTypeID("Prpr");
        var ref = new ActionReference();
        ref.putProperty(classProperty, behance);
        ref.putEnumerated(classApplication, typeOrdinal, enumTarget);
        var appDesc = app.executeActionGet(ref);
        if (appDesc.hasKey(behance)) {
            s = appDesc.getString(behance).split("@")[0];
        }
    }
    catch(e) {
        ;
    }
    return s;
    
}

function GetAdobeID()
{
    var s = "ERROR ID";
    try {
        var classApplication = charIDToTypeID('capp');
        var typeOrdinal      = charIDToTypeID('Ordn');
        var enumTarget       = charIDToTypeID('Trgt');
        var behance2         = charIDToTypeID('bhn2');
        var classProperty    = charIDToTypeID("Prpr");
        var ref = new ActionReference();
        ref.putProperty(classProperty, behance2);
        ref.putEnumerated(classApplication, typeOrdinal, enumTarget);
        var appDesc = app.executeActionGet(ref);
        if (appDesc.hasKey(behance2)) {
            s = appDesc.getString(behance2);
        }
    }
    catch(e) {
        ;
    }
    return s;
}

// Populate the Create panel with some options
// NOTE: the docType must match the case statement in openDocumentOfType in photoshop.js
function GetNewDocTypes()
{
    var s = '{"docType":"default","name":"Default Photoshop Size","icon":"psd"}';
    
    s += ', {"docType":"print","name":"Print Document","icon":"psd"}';
    s += ', {"docType":"photo","name":"Photo Document","icon":"psd"}';
    s += ', {"docType":"web","name":"Web Document","icon":"psd"}';
    s += ', {"docType":"mobile","name":"Mobile App Design Document","icon":"psd"}';
    s += ', {"docType":"iconography","name":"Iconography Document","icon":"psd"}';
    s += ', {"docType":"film","name":"Film & Video Document","icon":"psd"}';
    s += ', {"docType":"preset","name":"Document From Saved Preset","icon":"psd"}';
    s += ', {"docType":"custom","name":"Custom Document","icon":"psd"}';
    
    return s;
}

function GetRecentFiles()
{
    var s = '';
    if (app.recentFiles.length)
    {
        var l = app.recentFiles.length < 10 ? app.recentFiles.length : 10;
    
        for (var i = 0; i < l; i++)
        {
            s += '{"fullpath":"';
            s += app.recentFiles[i].fullName;
            s += '","name":"';
            s += unescape(app.recentFiles[i].name);
            s += '","icon":"psd"}'
            
            if (i < l - 1)
            {
                s += ',';
            }
        }
        s += ',{"fullpath":"open","name":"Open...","icon":"openicon"}';
    } else {
        s += '{"fullpath":"open","name":"Open...","icon":"openicon"}';
    }
    return s;
}

function SetDontShowAgain(inValue)
{
    try {
        var desc = new ActionDescriptor();
        desc.putBoolean( stringIDToTypeID( "show" ), ! inValue );
        app.putCustomOptions( "0685b2e9-19db-4679-90b9-34644fcc7884", desc, true );
    }
    catch(e) {
        ;
    }
}

function GetDontShowAgain()
{
    var returnValue = false;
    
    try {
        var desc = app.getCustomOptions( "0685b2e9-19db-4679-90b9-34644fcc7884" );
        var kshowStr = stringIDToTypeID( "show" );
        if ( desc.count > 0 && desc.hasKey( kshowStr ) ) {
            returnValue = ! desc.getBoolean( kshowStr );
        }
    }
    catch(e) {
        returnValue = false;
    }
    return returnValue;
}

function IsWindowsOS()
{
    if ( $.os.search(/windows/i) != -1 ) {
        return true;
    } else {
        return false;
    }
}
