/*************************************************************************
 *
 * ADOBE CONFIDENTIAL
 * ___________________
 *
 *  Copyright 2015 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 **************************************************************************/

/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50, sloppy: true, continue: true, todo: true, unparam: true */
/*globals $, app, BRUSH, FLfile, COLOR, JSXGlobals, Folder */

// Load other helper functions
// Get the root folder name from the scriptURI of current script
var jsxROOT = FLfile.uriToPlatformPath(app.scriptURI.split('/').slice(0, -1).join('/') + '/');
$.evalFile(jsxROOT + "brush.jsx");
$.evalFile(jsxROOT + "color.jsx");

// Layer types
var LayerType = {
    'NORMAL': 'normal',
    'GUIDE': 'guide',
    'GUIDED': 'guided',
    'MASK': 'mask',
    'MASKED': 'masked',
    'FOLDER': 'folder'
};

var ElementType = {
    'TEXT': 'text',
    'SHAPE': 'shape',
    'INSTANCE': 'instance',
    'MOVIECLIP': 'movie clip',
    'GRAPHIC': 'graphic',
    'BUTTON': 'button'
};

var FillStyle = {
    'SOLID': 'solid',
    'LIN_GRAD': 'linearGradient',
    'RAD_GRAD': 'radialGradient'
};

// Core overrides
$._ADBE_LIBS_CORE.isDocumentOpen = function (path) {
    var docs = app.documents || [];
    var i;

    for (i = 0; i < docs.length; ++i) {
        if (docs[i].path === path) {
            return true;
        }
    }

    return false;
};

$._ADBE_LIBS_FLPR = {
    loadAndSelectBrush: BRUSH.loadAndSelectBrush,
    setColor: COLOR.setColor,
    getTooltipState: function () {
        // Flash Pro has tooltips enabled always
        return 'true';
    },
    isAnalyticsEnabled: function () {
        return app.isAnalyticsEnabled();
    },
    getCurrentState: function () {
        try {
            var activeDoc = app.getDocumentDOM();
            if (activeDoc && activeDoc.timelines && activeDoc.currentTimeline >= 0 && activeDoc.currentTimeline < activeDoc.timelines.length) {
                var activeTimeline = activeDoc.timelines[activeDoc.currentTimeline];
                var selectedLayerId = activeTimeline.currentLayer;
                var docPath = activeDoc.path;
                if (!docPath) {
                    // If document is not saved, return just the name
                    docPath = activeDoc.name;
                }

                return JSON.stringify({
                    'path': docPath,
                    'layerID': selectedLayerId
                });
            }
        } catch (ignore) {}
        return JSON.stringify({
            'path': '',
            'layerID': -1
        });
    },
    isFontAvailable: function (style) {
        // TODO: Implement a function that returns true or false, depending on whether the given font is available
        // in your application.
        return 'false';
    },
    getLayerInfo: function () {
        // We return the information based on the current selection in this callback, which is what is needed to enable/disable
        // certain UI options. Its not returning the information for the entire layer
        var layerObject = {
            'name': '',
            'fullName': ''
        };
        var layerColors = [];

        try {
            var activeDoc = app.getDocumentDOM();
            if (activeDoc) {
                var mergeForSelectionFlag = activeDoc.mergeForSelection;
                activeDoc.mergeForSelection = true;
                var selections = activeDoc.selection;
                if (selections && selections.length > 0) {
                    // Get the values from the first selected object
                    var selection = selections[0];

                    var areEqual = function (colorData1, colorData2) {
                        var key;
                        if (colorData1 && colorData2) {
                            for (key in colorData1[0].value) {
                                if (colorData1[0].value.hasOwnProperty(key)) {
                                    if (!colorData2[0].value.hasOwnProperty(key) || Math.round(colorData1[0].value[key]) !== Math.round(colorData2[0].value[key])) {
                                        return false;
                                    }
                                }
                            }
                        }
                        return true;
                    };

                    var pushUnique = function (colorData, colorType) {
                        if (colorData === undefined) {
                            return;
                        }
                        var index;
                        for (index = 0; index < layerColors.length; index++) {
                            if (areEqual(layerColors[index].data, colorData)) {
                                return;
                            }
                        }
                        layerColors.push({
                            'colorType': colorType,
                            'data': colorData
                        });
                    };

                    layerObject.enableApplyText = false;

                    // Disable text temporarily
                    // if (selection.elementType === ElementType.TEXT) {
                    //    layerObject.enableApplyText = true;
                    //    layerObject.text = $._ADBE_LIBS_CORE.shortenString(selection.getTextString());

                    //    // TODO: populate the font info
                    //    // layerObject.fontInfo = getFontInfo();
                    //    // pushUnique(layerObject.fontInfo.color, JSXGlobals.PS_TEXT);
                    //}
                    // Get the fill and stroke color from selection, not from the global app settings
                    try {
                        var fill = selection.getCustomFill(false);
                        // TODO: Handle other fill types
                        if (fill && fill.style === FillStyle.SOLID && fill.color) {
                            pushUnique(COLOR.colorStringToData(fill.color), JSXGlobals.FILL);
                        }
                    } catch (ignore) {}

                    try {
                        // Get the fill style of stroke and extract the color from that
                        var stroke = selection.getCustomStroke(false);
                        if (stroke) {
                            var strokeFill = stroke.shapeFill;
                            // TODO: Handle other fill types
                            if (strokeFill && strokeFill.style === FillStyle.SOLID && strokeFill.color) {
                                pushUnique(COLOR.colorStringToData(strokeFill.color), JSXGlobals.STROKE);
                            }
                        }
                    } catch (ignore) {}
                    layerObject.colors = layerColors;

                    // Disabling graphic upload temporarily for the next CC Library Panel Release
                    // This will be enabled later 

                    /* if (selections.length === 1 && selections[0].elementType === ElementType.INSTANCE) {
                        // Enable the graphic upload only if there is a single symbol instance selected
                        // This will change in future though, when we allow graphic upload for any selection
                        layerObject.enableGraphicUpload = true;
                    } */
                }

                // Disabling graphic upload temporarily for the next CC Library Panel Release
                // This will be enabled later 

                // Currently we are giving priority to stage over library symbols. 
                // if there is any selection on stage then this loop will not run
                // else we will check is there any selection in library panel.
                // This is a temporary behavior which will change soon
                /* if (!layerObject.enableGraphicUpload || layerObject.enableGraphicUpload === false) {
                    var selItems = activeDoc.library.getSelectedItems();
                    var index, type;
                    if (selItems && selItems.length > 0) {
                        for (index = 0; index < selItems.length; index++) {
                            type = selItems[index].itemType;
                            if (type === ElementType.MOVIECLIP || type === ElementType.GRAPHIC || type === ElementType.BUTTON) {
                                layerObject.enableGraphicUpload = true;
                                break;
                            }
                        }
                    }
                } */

                layerObject.selectionExists = selections !== null;
                activeDoc.mergeForSelection = mergeForSelectionFlag;
                layerObject.kind = "";
                layerObject.enableApplyStyle = false;
                layerObject.enableShapeLayerApplyOperations = false;
                layerObject.libraryLinked = false;
                return JSON.stringify(layerObject);
            }
            return "";
        } catch (ex) {
            $._ADBE_LIBS_CORE.writeToLog('FLPR.jsx-getLayerInfo()', ex);
        }
        return JSON.stringify(layerObject);
    },
    placeAsset: function (filePath, libraryName, itemName, elementRef, modifiedTime, creationTime, isLinked) {
        try {
            var activeDoc = app.getDocumentDOM();
            if (activeDoc && filePath) {
                // Need to make a copy of the file to avoid overwrite
                var fileExtension = filePath.substr(filePath.lastIndexOf(".") + 1).toLowerCase();
                var destPath = Folder.temp.fsName + '/' + new Date().valueOf() + '.' + fileExtension;
                var sourceURI = FLfile.platformPathToURI(filePath);
                var destURI = FLfile.platformPathToURI(destPath);

                FLfile.copy(sourceURI, destURI);
                activeDoc.importCCLibAsset(destURI, elementRef, modifiedTime, itemName, isLinked);
            }
        } catch (ex) {
            $._ADBE_LIBS_CORE.writeToLog('FLPR.jsx-placeAsset()', ex);
        }
    },
    saveAssets: function (info, generateSecondaryFormat, dragAssetId) {
        try {
            var uploadData = [];
            var activeDoc = app.getDocumentDOM();
            if (activeDoc) {
                var flaPath = FLfile.platformPathToURI(Folder.temp.fsName + "/" + info.name + ".fla");
                var pngPath = FLfile.platformPathToURI(Folder.temp.fsName + "/" + info.name + ".png");
                var selections = activeDoc.selection;
                // We are currently enabling this for single selection of symbol instances
                // This will change in future when XD defines the other workflows
                var libraryUpload = true;
                var assets = [];
                if (selections && selections.length === 1) {
                    var sel = selections[0];
                    if (sel.elementType === ElementType.INSTANCE) {
                        libraryUpload = false;
                        assets = activeDoc.exportSelectionToSymbol(flaPath, pngPath, {'fromLibrary': false});
                    }
                }
                // Current behavior is we are uploading symbols either from stag or library.
                if (libraryUpload) {
                    var selItems = activeDoc.library.getSelectedItems();
                    if (selItems.length > 0) {
                        assets = activeDoc.exportSelectionToSymbol(flaPath, pngPath, {'fromLibrary': true});
                    }
                }
                var asset, index;
                for (index = 0; index < assets.length; index++) {
                    if (assets[index]) {
                        asset = {};
                        asset.layerName = assets[index].name;
                        asset.files = [];
                        if (assets[index].primaryPath) {
                            asset.files.push({'path': assets[index].primaryPath, 'relationship': 'primary'});
                            if (assets[index].renditionPath) {
                                asset.files.push({'path': assets[index].renditionPath, 'relationship': 'rendition'});
                            }
                        }
                        uploadData.push(asset);
                    }
                }
            }
            return JSON.stringify(uploadData);
        } catch (ex) {
            $._ADBE_LIBS_CORE.writeToLog('FLPR.jsx-saveAssets()', ex);
        }
    },
    openAssetForEdit: function (filePath, renditionPath) {
        try {
            var sourceURI = FLfile.platformPathToURI(filePath);
            var newDoc = app.openDocument(sourceURI, {'addToRecent': false, 'renditionPath': renditionPath});
            return newDoc.name;
        } catch (ex) {
            $._ADBE_LIBS_CORE.writeToLog('FLPR.jsx-openAssetForEdit()', ex);
        }
    },
    reportEvent: function (eventName, properties) {
        try {
            if (eventName === "createElement" || eventName === "useElement" || eventName === "createLink") {
                // Log events to Highbeam so Design Library usage can be compared
                // to usage of other Flash features.
                var highbeamDataGroupName = "Design Library";

                // Helper to handle null and undefined properties
                var safeGetStringProperty = function (property) {
                    return property || "N/A";
                };

                var data = {
                    'eventName': safeGetStringProperty(eventName),
                    'libraryID': safeGetStringProperty(properties.libraryID),
                    'elementType': safeGetStringProperty(properties.elementType),
                    'opType': safeGetStringProperty(properties.opType)
                };

                app.logPIPEvent(highbeamDataGroupName, JSON.stringify(data));

                return true;
            }

        } catch (ex) {
            $._ADBE_LIBS_CORE.writeToLog('FLPR.jsx-reportEvent()', ex);
        }

        return false;
    }
};
