(function (paw) {
    function EvaluationsTableNormalization($root) {
        this.$root = $root;

        this.$ntable;
        this.$tableHeader;
        this.$tableBody;
        this.headerValues = [];
    }

    EvaluationsTableNormalization.prototype.normalizeTable = function () {
        var self = this;
        this.$ntable = $('<table></table>');
        this.$tableHeader = $('<thead></thead>');
        this.$tableBody = $('<tbody></tbody>');
        self.$ntable.append(self.$tableHeader);
        self.$ntable.append(self.$tableBody);

        this.$root.find('.evaluation-panel').each(function (paneli) {
            var $evalPanel = $(this);
            var extractedValues = self.extractValues($evalPanel, paneli === 0);

            $evalPanel.find('table.eval-category-header').each(function () {
                $(this).find('tbody tr').each(function (rowi) {
                    var $nrow = $('<tr></tr>');

                    for (var i = 0; i < extractedValues.length; i++) {
                        $nrow.append('<td>' + extractedValues[i] + '</td>');
                    }

                    $(this).find('td').each(function (celli) {
                        // skip first cell - hidden values
                        if (celli === 0) {
                            return;
                        }
                        var $cell = $(this);
                        var value;
                        switch (celli) {
                            case 1: {
                                value = paw.utils.value.trimString($cell.find('a').text());
                                break;
                            }
                            case 2: {
                                value = paw.utils.value.trimString(self.parseValueFromSelect2($cell));
                                break;
                            }
                            case 3: {
                                value = paw.utils.value.trimString($cell.text());
                                break;
                            }
                            case 4: {
                                value = paw.utils.value.trimString($cell.text());
                                break;
                            }
                            case 7: {
                                value = paw.utils.value.trimString($cell.find('input').val());
                                break;
                            }
                            default:
                                value = "";
                                break;
                        }
                        $nrow.append('<td>' + value + '</td>');
                    });

                    self.$tableBody.append($nrow);
                });
            });
        });
        return this.$ntable;
    };

    EvaluationsTableNormalization.prototype.extractValues = function ($evalPanel, constructHeader) {
        var self = this;
        var $evalTable = $evalPanel.children('table.evaluation-table');
        var extractedValues = [];

        var $headerRow = $('<tr></tr>');
        $evalTable.find('td').each(function (celli) {
            var $cell = $(this);
            var title;
            var value;
            switch (celli) {
                case 0: {
                    var $v = $cell.find('.open-position[title]');
                    title = paw.utils.value.trimString($v.attr('title'));
                    value = paw.utils.value.trimString($v.children('span').text());
                    break;
                }
                case 1: {
                    title = paw.utils.value.trimString($cell.attr('title'));
                    value = paw.utils.value.trimString($cell.find('input').val());
                    break;
                }
                case 2: {
                    title = paw.utils.value.trimString($cell.attr('title'));
                    value = paw.utils.value.trimString(self.parseValueFromSelect2($cell));
                    break;
                }
                case 3: {
                    title = paw.utils.value.trimString($cell.attr('title'));
                    value = paw.utils.value.trimString($cell.find('input').val());
                    break;
                }
                case 4: {
                    title = paw.utils.value.trimString($cell.attr('title'));
                    value = paw.utils.value.trimString(self.parseValueFromSelect2($cell));
                    break;
                }
                case 5: {
                    title = paw.utils.value.trimString($cell.attr('title'));
                    value = paw.utils.value.trimString($cell.find('span').text());
                    break;
                }
                default:
                    title = "";
                    value = "";
                    break;
            }

            extractedValues.push(value);

            if (constructHeader) {
                self.headerValues.push(title);
                $headerRow.append('<th>' + title + '</th>');
            }
        });

        if (constructHeader) {
            $evalPanel.children('.panel-collapse').children('table.table').find('tr th').each(function (celli) {
                var $cell = $(this);
                var title = $cell.text();
                self.headerValues.push(title);
                $headerRow.append('<th>' + title + '</th>');
            });
            self.$tableHeader.append($headerRow);
        }
        return extractedValues;
    };

    EvaluationsTableNormalization.prototype.parseValueFromSelect2 = function ($cell, fn) {
        var $holder = $cell.find('span.select2-selection__rendered');
        if ($holder.length > 0) {
            return $holder.contents().filter(function () {
                return this.nodeType === 3; // Filter out text nodes
            }).text().trim();
        }
        if (paw.utils.value.isFunction(fn)) {
            return fn($cell);
        }
        return $holder.text();
    };

    function EvaluationsExporter($root, features) {
        this.$root = $root;
        this.features = features;
        this.ntable = new EvaluationsTableNormalization(this.$root);
    }

    EvaluationsExporter.create = function ($root, features) {
        var exporter = new EvaluationsExporter($root, features);
        exporter.init();
    };

    EvaluationsExporter.prototype.init = function () {
        var self = this;
        paw.mod.excel.Excel.prepareExporter($(this.$root.children()[0]), this.features, null, function () {
            self.exportExcel();
        });
    };

    EvaluationsExporter.prototype.compileNormalizedTable = function () {
        return this.ntable.normalizeTable();
    };

    EvaluationsExporter.prototype.exportExcel = function () {
        this.compileNormalizedTable();
        paw.mod.excel.Excel.exportFromHTMLTable(this.ntable.$ntable);
    };

    paw.view.employees.EvaluationsExporter = EvaluationsExporter;
})(paw);