/*
 * ADOBE CONFIDENTIAL
 *
 * Copyright (c) 2013 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, indent: 4, bitwise: true */
/*global define: true, graphite: true*/

define([
    'underscore',
    'backbone',
    'ccweb.files.extract/Constants',
    'ccweb.files.extract/collections/LayerCollection',
    'ccweb.files.extract/models/LayerCompModel',
    'ccweb.files.extract/models/LayerModelMap',
    'ccweb.files.extract/utils/MeasurementUtil',
    'parfait/PSDModel',
    'ccweb.files.extract/utils/UTF8'
], function (_, Backbone, Constants, LayerCollection, LayerCompModel, LayerModelMap, MeasurementUtil, PSDModel, UTF8) {
    'use strict';
    function mergeSpriteSheetAndJSONData(jsonData, spriteSheetData) {
        var layerMap = [],
            mergeLayers = function (layers) {
                _.each(layers, function (layer) {
                    var mappedLayer = layerMap[layer.layerId];
                    layer.spriteSheet = mappedLayer.spriteSheet;
                    if (mappedLayer.flattenedSprite) {
                        layer.flattenedSprite = mappedLayer.flattenedSprite;
                    }

                    if (layer.children) {
                        mergeLayers(layer.children);
                    }
                });
            };

        _.each(spriteSheetData.layers, function (layer) {
            layerMap[layer.layerId] = layer;
        });

        mergeLayers(jsonData.children);
        jsonData.dataType = 'complete';

        return jsonData;
    }
    
    var DwPSDModel = PSDModel.extend({
        defaults: {
            id: '',
            info: '',
            imgdata: {
                originalFile: '',
                bounds: {
                    bottom: 0,
                    left: 0,
                    right: 0,
                    top: 0
                }
            },
            isArtboardPSD: false,
            artboardsBounds: null, //The union of the bounds of all the artboards. Used for ZoomToFit
            artboards: null,
            layerCollection: null,
            layerComps: null,
            layerCompId: null,
            extractedStyles: null,
            localContent: false,
            path: "",
            md5: "",
            welcomeExp: false,
            status: 0
        },

        initialize: function (options) {
            if (options.id) {
                this.id = options.id.replace(/\//g, "_");
            }
            if (options.md5) {
                this.md5 = options.md5.replace(/\//g, "_").replace(/\,/g, "_");
            }
        },

        parse: function (response) {
            response.dataType = response.dataType || 'complete';
            if (response.dataType === 'spriteSheetOnly') {
                if (this.jsonData) {
                    response = mergeSpriteSheetAndJSONData(this.jsonData, response);
                    delete this.jsonData;
                } else {
                    this.spriteSheetData = response;
                    return;
                }
            } else if (response.dataType === 'JSONOnly') {
                if (this.spriteSheetData) {
                    response = mergeSpriteSheetAndJSONData(response, this.spriteSheetData);
                    delete this.spriteSheetData;
                } else {
                    this.jsonData = response;
                }
            }

            this.decodeChildNames(response.children);
            this.set('imgdata', response.imgdata);
            this.set('info', response.info);
            this.set('width', response.imgdata.bounds.right);
            this.set('height', response.imgdata.bounds.bottom);
            this.set('dataType', response.dataType);
            LayerModelMap.reset();
            var layerCollection = new LayerCollection();
            layerCollection.add(layerCollection.parse(response.children), {parse: true});
            this.set('layerCollection', layerCollection);
            
            //Calc the artboard info
            var artboardsList,
                artboardsBounds = null;

            artboardsList = layerCollection.reduce(function(array, layer) {
                if (layer.get('type') === Constants.Type.LAYER_ARTBOARD) {
                    array.push(layer);
                }
                return array;
            }, []);
            if (artboardsList.length > 0) {
                artboardsBounds = MeasurementUtil.calcLayerGroupBounds(artboardsList, this);
            }
            this.set('isArtboardPSD', artboardsList.length > 0);
            this.set('artboardsBounds', artboardsBounds);
            this.set('artboards', response.imgdata.artboards);

            //trigger the numLayer event to track # of layers in psd
            graphite.events.trigger('num-layers', response.imgdata);

            this.extractStyles();

            var layerComps = this.extractLayerComps(response.layerComps);
            this.set('layerComps', layerComps);
            graphite.events.trigger('layerCompsLoaded');

            var layerCompId = this.get('layerCompId');
            if (layerComps && layerComps.length && !layerCompId) {
                //Checking !layerCompId ensures that we only fire this once per PSD
                graphite.events.trigger('layerCompShown');
            }
            graphite.events.trigger("psd-processed", this.get('md5'));
            this.set('status', 200);
            this.unset('errorInfo');
        }
    });
    
    return DwPSDModel;
});

