/*
 * #%L
 * gitools-ui-app
 * %%
 * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */
package org.gitools.ui.app.datasources.biomart.filter;

import org.gitools.datasources.biomart.restful.model.Filter;
import org.gitools.datasources.biomart.restful.model.FilterDescription;
import org.gitools.datasources.biomart.restful.model.Option;
import org.gitools.ui.core.Application;
import org.gitools.ui.core.utils.FileChooserUtils;
import org.gitools.ui.platform.dialog.ExceptionGlassPane;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class FilterTextComponent extends FilterComponent {

    private String component;
    private final Integer FIELD_HEIGHT = 45;
    private final Integer TEXTAREA_HEIGHT = 130;

    FilterTextComponent(FilterDescription d, FilterDescriptionPanel parent) {

        super(d, parent);
        initComponents();

        buildComponent();


    }

    FilterTextComponent(Option o) {

        super(o);

        initComponents();

        buildComponent();

    }

    /**
     * This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        txtField = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        txtArea = new javax.swing.JTextArea();
        nameDescription = new javax.swing.JLabel();
        browsePanel = new javax.swing.JPanel();
        folder = new javax.swing.JTextField();
        browse = new javax.swing.JButton();

        jLabel1.setText("jLabel1");

        txtArea.setColumns(20);
        txtArea.setRows(5);
        jScrollPane1.setViewportView(txtArea);

        nameDescription.setText("Name");

        folder.setEnabled(false);

        browse.setLabel("Browse...");
        browse.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                selectFileAction(evt);
            }
        });

        javax.swing.GroupLayout browsePanelLayout = new javax.swing.GroupLayout(browsePanel);
        browsePanel.setLayout(browsePanelLayout);
        browsePanelLayout.setHorizontalGroup(browsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.TRAILING, browsePanelLayout.createSequentialGroup().addComponent(folder, javax.swing.GroupLayout.DEFAULT_SIZE, 282, Short.MAX_VALUE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(browse)));
        browsePanelLayout.setVerticalGroup(browsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(browsePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(folder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(browse)));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addContainerGap().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(browsePanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE).addComponent(txtField, javax.swing.GroupLayout.DEFAULT_SIZE, 361, Short.MAX_VALUE).addGroup(layout.createSequentialGroup().addComponent(nameDescription, javax.swing.GroupLayout.DEFAULT_SIZE, 69, Short.MAX_VALUE).addGap(292, 292, 292))).addContainerGap()));
        layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(6, 6, 6).addComponent(nameDescription).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED).addComponent(txtField, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(browsePanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
    }// </editor-fold>//GEN-END:initComponents

    private void selectFileAction(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_selectFileAction

        File selPath = FileChooserUtils.selectFile("Select file", folder.getText(), FileChooserUtils.MODE_OPEN).getFile();

        if (selPath != null) {

            folder.setText(selPath.getAbsolutePath());

            try {

                txtArea.setText(readFileAsString(folder.getText()));

            } catch (IOException ex) {
                ExceptionGlassPane dlg = new ExceptionGlassPane(Application.get(), ex);
                dlg.setVisible(true);
            }


        }


    }//GEN-LAST:event_selectFileAction

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton browse;
    private javax.swing.JPanel browsePanel;
    private javax.swing.JTextField folder;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel nameDescription;
    private javax.swing.JTextArea txtArea;
    private javax.swing.JTextField txtField;
    // End of variables declaration//GEN-END:variables

    //FIXME :	Test the way how to initialise components (default value or empty string).
    //			Not clear from Biomart

    private void buildComponent() {

        String txt = null;

        if (parentPanel != null && parentPanel.getRenderLabel()) {
            nameDescription.setVisible(true);
        } else {
            nameDescription.setVisible(false);
        }

        if (filterDescription != null) {
            txt = filterDescription.getDefaultValue() != null ? filterDescription.getDefaultValue() : "";

            if (filterDescription.getMultipleValues() == 0) {
                component = "Field";
            } else {
                component = "TextArea";
            }
        } else {
            if (filterOptions != null) {
                txt = filterOptions.getDefaultValue() != null ? filterOptions.getDefaultValue() : "";

                if (filterOptions.getMultipleValues() == 0) {
                    component = "Field";
                } else {
                    component = "TextArea";
                }
            } else {
                return;
            }
        }

        if (component.equals("Field")) {
            txtField.setAlignmentY(TOP_ALIGNMENT);

            txtField.setText(txt);

            txtField.setVisible(true);

            jScrollPane1.setVisible(false);

            txtArea.setVisible(false);

            browsePanel.setVisible(false);

            currentHeight = FIELD_HEIGHT;
        } else {
            component = "TextArea";

            jScrollPane1.setAlignmentY(TOP_ALIGNMENT);

            jScrollPane1.setVisible(true);

            txtArea.setAlignmentY(TOP_ALIGNMENT);

            txtArea.setVisible(true);

            txtArea.setText("");

            browsePanel.setVisible(true);

            txtField.setVisible(false);

            txtField.setAlignmentY(BOTTOM_ALIGNMENT);

            currentHeight = TEXTAREA_HEIGHT;
        }

        if (filterDescription != null && filterDescription.getDisplayName() != null)

        {
            nameDescription.setText(filterDescription.getDisplayName());
        }

    }


    @Override
    public List<Filter> getFilters() {

        List<Filter> filters = new ArrayList<>();

        Filter f = new Filter();

        // When filterDescription is null,
        // means this component is a child (it belongs to a container component)
        if (filterDescription != null && filterDescription.getInternalName() != null) {
            f.setName(filterDescription.getInternalName());
        }

        if (component.equals("Field")) {
            f.setValue(txtField.getText());
        } else {
            f.setValue(txtArea.getText().replace("\n", ","));
        }

        f.setValue(f.getValue().replace("\\", "\\\\"));

        f.setValue(f.getValue().replace("\"", "\\\""));

        while (f.getValue().startsWith(","))
            f.setValue(f.getValue().substring(1));
        while (f.getValue().endsWith(","))
            f.setValue(f.getValue().substring(0, f.getValue().length() - 1));

        filters.add(f);

        return filters;
    }

    @Override
    //FIXME : Check initial component value (default value or empty string). Not clear from Biomart
    public Boolean hasChanged() {

        if (component.equals("Field")) {
            return (txtField.getText().equals((filterDescription.getDefaultValue() != null) ? filterDescription.getDefaultValue() : ""));
        } else {
            return (txtArea.getText().equals(filterDescription.getValue()));
        }

    }

    /**
     * Read file as String. Content is stored in a Filter object.
     * Fix: Move into utils package
     *
     * @param filePath
     * @return
     * @throws java.io.IOException
     */

    private static String readFileAsString(String filePath) throws java.io.IOException {
        byte[] buffer = new byte[(int) new File(filePath).length()];
        BufferedInputStream f = new BufferedInputStream(new FileInputStream(filePath));
        f.read(buffer);
        return new String(buffer);
    }

    @Override
    public void setListOptions(List<Option> optionList) {
    }
}
