(function(paw){
    function PawExcelCompiler(){

    }

    PawExcelCompiler.MimeType = {
        XLSX: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    };

    PawExcelCompiler.prototype.generateXlsxFile = function(excel){
        var filename = excel.settings.filename + '.xlsx';
        return excel.workbook.xlsx.writeBuffer().then(buffer => {
            var blob = new Blob([buffer], { type: PawExcelCompiler.XLSX });
            // Use browser-specific method to download file
            if (navigator.msSaveBlob) { // For IE and Edge
                navigator.msSaveBlob(blob, filename);
            } else { // For other browsers
                var link = document.createElement('a');
                link.href = window.URL.createObjectURL(blob);
                link.download = filename;
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        });
    };

    PawExcelCompiler.prototype.fromHTMLTable = function($table, excel, processCell, processRow, lastRowIndex){
        var self = this;
        if(paw.utils.value.notFunction(processCell)){
            processCell = function(){};
        }
        if(paw.utils.value.notFunction(processRow)){
            processRow = function(){};
        }
        if(paw.utils.value.notSet(lastRowIndex)){
            lastRowIndex = 0;
        }

        // add empty row representing title row
        if (excel.settings.addTitleRow && lastRowIndex === 0) {
            excel.worksheet.addRow();
            lastRowIndex++;
        }

        var $rows = $table.find('tr');
        var ri = lastRowIndex; // process row index
        var rri = ri; // insterted row index
        let rci = 0; // inserted column index
        $rows.each(function(){
            var $row = $(this);
            var rowDirective = $row.attr('data-paw-export');
            if (rowDirective === 'ignore') {
                ri++;
                return;
            }

            let ci = 0; // process column index
            let er = rri + 1;
            rci = 0;

            let $cols = $row.find('td, th');
            /*if (ri === 0 && excel.settings.addTitleRow && lastRowIndex === 0) {
                self.addTitleRow($cols.length - excel.settings.ignoreColumns.length, excel);
                ri++;
                rri++;
                er = rri + 1;
            }*/

            $cols.each(function () {
                var $cell = $(this);
                var colDirective = $cell.attr('data-paw-export');

                if (colDirective === 'ignore' ||
                    excel.settings.ignoreColumns.indexOf(ci) > -1 ||
                    (excel.settings.ignoreHiddenColumns && ($cell.css('display') === 'none' || $cell.css('visibility') === 'hidden'))) {
                    ci++;
                    return;
                }

                var cellId = self.calcCellId(rci, er);
                var cell = excel.worksheet.getCell(cellId);

                var value;
                var $v = $cell.find('[data-paw-export=value]');
                if ($v.length > 0) {
                    value = paw.utils.value.trimString(self.parseValue($v));
                }
                else {
                    value = paw.utils.value.trimString($cell.text());
                }

                cell.value = value.length > 0 && paw.utils.value.isNumeric(value) ? paw.utils.value.strToNum(value) : value;

                paw.mod.excel.excelStyle.HTMLStyleToExcel($cell, cell, excel);

                processCell({
                    $cell: $cell,  
                    $row: $row, 
                    rowIndex: ri,
                    columnIndex: rci,
                    cellId: cellId,
                    excel: excel
                });
                ci++;
                rci++;
            });
            processRow($row);
            ri++;
            rri++;
        });

        self.addTitleRow(rci, excel);

        return {
            rowIndex: ri
        };
    };

    PawExcelCompiler.prototype.calcCellId = function(colIndex, rowIndex){
        let ec = String.fromCharCode(65 + colIndex);
        return ec + rowIndex;
    };

    PawExcelCompiler.prototype.addTitleRow = function(colsSize, excel){
        var fromCellId = this.calcCellId(0, 1);
        var toCellId = this.calcCellId(colsSize - 1, 1);
        excel.worksheet.addRow();
        excel.worksheet.mergeCells(fromCellId + ':' + toCellId);
        
        var mergedCell = excel.worksheet.getCell(fromCellId);
        mergedCell.alignment = { horizontal: 'center' };
        mergedCell.value = excel.settings.filename;
    };

    PawExcelCompiler.prototype.parseValue = function ($v) {
        var tag = $v.prop('tagName').toLowerCase();
        switch (tag) {
            case 'input':
                if ($v.attr('type') === 'checkbox') {
                    return paw.utils.value.boolToStr($v.is(':checked'));
                }
                return $v.val();
            case 'select':
                return $v.children(':selected').text();
            default:
                return $v.text();
        }
    };

    paw.mod.excel.excelCompiler = new PawExcelCompiler();
})(paw);