/**
 * An Office Open XML SpreasheetML implementation according to the [ISO/IEC 29500-1:2012][1].
 *
 * [1]: http://www.iso.org/iso/home/store/catalogue_ics/catalogue_detail_ics.htm?csnumber=61750
 *
 * Only a small subset of that standard is implemented.
 *
 * @private
 */
Ext.define('Ext.exporter.file.ooxml.Excel', {
    extend: 'Ext.exporter.file.ooxml.XmlRels',
 
    requires: [
        'Ext.exporter.file.zip.Archive',
        'Ext.exporter.file.ooxml.excel.Workbook',
        'Ext.exporter.file.ooxml.Relationships',
        'Ext.exporter.file.ooxml.ContentTypes',
        'Ext.exporter.file.ooxml.CoreProperties'
    ],
 
    config: {
        /**
         * @cfg {Ext.exporter.file.ooxml.CoreProperties} [properties]
         *
         * Core properties of the Excel file
         */
        properties: null,
        /**
         * @cfg {Ext.exporter.file.ooxml.Workbook} workbook
         *
         * At least one Workbook needs to be in the file
         */
        workbook: {}
    },
 
    folder: '/',
    fileName: null,
 
    tpl: [],
 
    constructor: function(config){
        var ret = this.callParent([config]);
 
        if(!this.getWorkbook()){
            this.setWorkbook({});
        }
 
        return ret;
    },
 
    destroy: function() {
        var me = this;
        
        me.setWorkbook(null);
        me.setProperties(null);
        me.setRelationships(null);
        me.callParent();
    },
 
    render: function(){
        var files = {},
            paths, path, content, i, len, zip;
 
        this.collectFiles(files);
        // zip all files and return the zip content 
        paths = Ext.Object.getKeys(files);
        len = paths.length;
        if(!len){
            return;
        }
 
        zip = new Ext.exporter.file.zip.Archive();
        for(= 0; i < len; i++){
            path = paths[i];
            content = files[path];
            path = path.substr(1);
            if(path.indexOf('.xml') !== -1 || path.indexOf('.rel') !== -1) {
                zip.addFile({
                    path: path,
                    data: content
                });
            }
        }
        content = zip.getContent();
        zip = Ext.destroy(zip);
 
        return content;
    },
 
    collectFiles: function(files){
        var contentTypes = new Ext.exporter.file.ooxml.ContentTypes(),
            wb = this.getWorkbook(),
            props = this.getProperties(),
            types = [];
 
        wb.collectFiles(files);
        if(props){
            contentTypes.addContentType(props.getContentType());
            files[props.getPath()] = props.render();
        }
        wb.collectContentTypes(types);
        contentTypes.addContentType(types);
 
        files[contentTypes.getPath()] = contentTypes.render();
        Ext.destroy(contentTypes);
 
        this.collectRelationshipsFiles(files);
    },
 
    applyProperties: function(data){
        if(!data || data.isCoreProperties){
            return data;
        }
 
        return new Ext.exporter.file.ooxml.CoreProperties(data);
    },
 
    updateProperties: function(data, oldData){
        var rels = this.getRelationships();
 
        if(oldData){
            rels.removeRelationship(oldData.getRelationship());
            oldData.destroy();
        }
        if(data){
            rels.addRelationship(data.getRelationship());
        }
    },
 
    applyWorkbook: function(data){
        if(!data || data.isWorkbook){
            return data;
        }
 
        return new Ext.exporter.file.ooxml.excel.Workbook(data);
    },
 
    updateWorkbook: function(data, oldData){
        var rels = this.getRelationships();
 
        if(oldData){
            rels.removeRelationship(oldData.getRelationship());
            oldData.destroy();
        }
        if(data){
            rels.addRelationship(data.getRelationship());
        }
    },
 
    /**
     * Convenience method to add worksheets.
     *
     * @param {Object/Array} config
     * @return {Ext.exporter.file.ooxml.excel.Worksheet/Ext.exporter.file.ooxml.excel.Worksheet[]}
     */
    addWorksheet: function(config){
        return this.getWorkbook().addWorksheet(config);
    },
 
    /**
     * Convenience method to add a style.
     *
     * @param {Ext.exporter.file.Style} config
     * @return {Number} Index of the cell style
     */
    addStyle: function(config){
        return this.getWorkbook().getStylesheet().addStyle(config);
    },
 
    /**
     * Convenience method to add a style.
     *
     * @param {Ext.exporter.file.Style} config
     * @return {Number} Index of the cell style
     */
    addCellStyle: function(config){
        return this.getWorkbook().getStylesheet().addCellStyle(config);
    }
 
});