package com.ruoyi.common.dev.gui;

import com.ruoyi.common.utils.StringUtils;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.util.List;

public class FileField extends Box
{
    private       String     lastPath;
    private       String     path;
    private final JTextField textField;
    private       String     filter;
    private       String     name;
    private       int        mode = JFileChooser.FILES_ONLY;
    private FileFilter fileFilter = new FileFilter()
    {
        @Override
        public boolean accept(File f)
        {
            if(f.isFile())
            {
                if(StringUtils.isNotEmpty(filter))
                {
                    return f.getName().endsWith(filter);
                }
            }
            return true;
        }

        @Override
        public String getDescription()
        {
            if(StringUtils.isNotEmpty(filter))
            {
                return "*" + filter;
            }
            return null;
        }
    };

    public FileField(String name)
    {
        super(BoxLayout.X_AXIS);
        this.name = name;
        textField = new JTextField();
        lastPath = System.getProperty("user.dir");
        Setup();
    }

    private void Setup()
    {
        JLabel l = new JLabel(name);
        JButton button = new JButton("选择");
        Dimension labelMinimumSize = l.getMinimumSize();
        Dimension compMinimumSize = textField.getMinimumSize();
        Dimension buttonMinimumSize = button.getMinimumSize();
        labelMinimumSize.width = 128;
        l.setHorizontalAlignment(SwingConstants.RIGHT);
        l.setMinimumSize(labelMinimumSize);
        l.setPreferredSize(labelMinimumSize);
        l.setMaximumSize(labelMinimumSize);
        compMinimumSize.width = 256;
        textField.setMinimumSize(compMinimumSize);
        Dimension compPreferredSize = textField.getPreferredSize();
        compPreferredSize.width = 256;
        textField.setPreferredSize(compPreferredSize);
        buttonMinimumSize.width = 64;
        button.setHorizontalAlignment(SwingConstants.CENTER);
        button.setMinimumSize(buttonMinimumSize);
        button.setPreferredSize(buttonMinimumSize);
        button.setMaximumSize(buttonMinimumSize);
        this.add(l);
        this.add(textField);
        this.add(button);
        this.setMinimumSize(new Dimension(labelMinimumSize.width + compMinimumSize.width, Math.max(labelMinimumSize.height, compMinimumSize.height)));
        this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Math.max(labelMinimumSize.height, compMinimumSize.height)));
        button.addActionListener((x) -> OpenFileChooser());

        textField.setDragEnabled(true);
        new DropTarget(textField, DnDConstants.ACTION_COPY_OR_MOVE, new DropTargetAdapter()
        {
            @Override
            public void drop(DropTargetDropEvent dt)
            {
                try
                {
                    if(dt.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
                    {
                        dt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
                        java.util.List<File> files = (List<File>)dt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
                        File first = files.get(0);
                        switch(mode)
                        {
                            case JFileChooser.FILES_ONLY:
                                if(first.isFile())
                                {
                                    if(fileFilter.accept(first))
                                        SetPath(first);
                                    return;
                                }
                                break;
                            case JFileChooser.DIRECTORIES_ONLY:
                                if(!first.isFile())
                                {
                                    SetPath(first);
                                    return;
                                }
                                break;
                            case JFileChooser.FILES_AND_DIRECTORIES:
                                if(!first.isFile() || fileFilter.accept(first))
                                    SetPath(first);
                                return;
                        }
                        return;
                    }
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
                dt.rejectDrop();
            }
        });
    }

    private void OpenFileChooser()
    {
        JFileChooser jFileChooser = new JFileChooser(lastPath);
        jFileChooser.setDialogTitle("选择" + name);
        jFileChooser.addActionListener((x) -> {
            File currentDirectory = jFileChooser.getCurrentDirectory();
            if(null != currentDirectory)
                lastPath = currentDirectory.getAbsolutePath();

            if(JFileChooser.APPROVE_SELECTION.equals(x.getActionCommand()))
            {
                File selectedFile = jFileChooser.getSelectedFile();
                SetPath(selectedFile);
            }
        });
        jFileChooser.setFileSelectionMode(mode);
        jFileChooser.setFileFilter(fileFilter);
        jFileChooser.showOpenDialog(this);
    }

    public void SetLastPath(String path)
    {
        if(StringUtils.isEmpty(path))
            lastPath = System.getProperty("user.dir");
        else
        {
            File file = new File(path);
            if(file.exists())
            {
                if(!file.isDirectory())
                    file = file.getParentFile();
                try
                {
                    lastPath = file.getCanonicalPath();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    lastPath = file.getAbsolutePath();
                }
            }
            else
                lastPath = System.getProperty("user.dir");
        }
    }

    private void SetPath(File selectedFile)
    {
        if(null != selectedFile)
        {
            path = selectedFile.getAbsolutePath();
            lastPath = selectedFile.getParent();
        }
        else
        {
            path = null;
        }
        textField.setText(null != path ? path : "");
    }

    public void SetPath(String path)
    {
        SetPath(StringUtils.isNotEmpty(path) ? new File(path) : null);
    }

    public void Reset()
    {
        path = null;
        textField.setText("");
    }

    public String Path()
    {
        return textField.getText();
    }

    public void SetFilter(String filter)
    {
        this.filter = filter;
    }

    public void SetMode(int mode)
    {
        this.mode = mode;
    }
}
