/*
 * Copyright (c) 2015, StrategyQuant - All rights reserved.
 *
 * Code in this file was made in a good faith that it is correct and does what it should. 
 * If you found a bug in this code OR you have an improvement suggestion OR you want to include 
 * your own code snippet into our standard library please contact us at:
 * http://tasks.strategyquant.com/projects/snippets/
 *
 * This code can be used only within StrategyQuant products. 
 * Every owner of valid (free, trial or commercial) license of any StrategyQuant product 
 * is allowed to freely use, copy, modify or make derivative work of this code without limitations,
 * to be used in all StrategyQuant products and share his/her modifications or derivative work 
 * with the StrategyQuant community.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES 
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */
package com.strategyquant.extend.DatabankActions;

import java.io.File;
import java.io.WriteAbortedException;
import java.util.ArrayList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.strategyquant.core.gui.windows.common.JCommonDialog;
import com.strategyquant.gui.panels.MultiSaveListener;
import com.strategyquant.gui.panels.MultiSavePanel;
import com.strategyquant.lib.app.MainApp;
import com.strategyquant.lib.databank.Databank;
import com.strategyquant.lib.databank.DatabankAction;
import com.strategyquant.lib.files.RecentFilesAndPaths;
import com.strategyquant.lib.files.NewFileHandler;
import com.strategyquant.lib.files.SaveFilesTask;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.plugins.SQGlobalEventMsg;
import com.strategyquant.lib.plugins.SQGlobalEvents;
import com.strategyquant.lib.results.SQResultsGroup;
import com.strategyquant.lib.settings.SQCoreConst;
import com.strategyquant.lib.utils.SQUtils;

public class SaveStrategy extends DatabankAction implements MultiSaveListener {

	public static final Logger Log = LoggerFactory.getLogger("SaveStrategy");

	public SaveStrategy() {
		setName("Save:"+L.t("Strategy project (.str)"));
	}
	
	@Override
	public void execute(Databank databank) {
		ArrayList<SQResultsGroup> strategyResults = databank.getSelectedResults();
		
		if(strategyResults.size() <= 0) {
			JOptionPane.showMessageDialog(MainApp.getFrame(), 
					L.t("Please select at least one strategy using checkbox."),
					L.t("Info"),
	    		    JOptionPane.INFORMATION_MESSAGE);	

			return;
		}
		
		if(strategyResults.size() == 1) {
			saveOneFile(strategyResults);
			
		} else {
			saveMultipleFiles(strategyResults);
		}
	}
	
	private void saveMultipleFiles(ArrayList<SQResultsGroup> strategyResults) {
		MultiSavePanel panel = new MultiSavePanel(strategyResults, RecentFilesAndPaths.SAVE_STRATEGY, this);
		
		JCommonDialog dlg = new JCommonDialog(panel, MainApp.getFrame(), true, L.t("Save strategies"), 530, 200);
		dlg.setLocationRelativeTo(MainApp.getFrame());
		dlg.setVisible(true);
	}

	@Override
	public void directorySelected(String directory, String prefix, ArrayList<SQResultsGroup> strategyResults) {
		try {
	        SaveFilesTask task = new SaveFilesTask(strategyResults, directory, prefix);
	    	task.save();
	     	
			// now send an event that file was saved
			SQGlobalEvents.getInstance().callChangeEvent(SQGlobalEventMsg.SAVE_FINISHED, null);
		} catch(Exception e) {
			Log.error("Error!!! Unable to save report files: ", e);
			SQUtils.showExceptionDialog(new Exception("Error!!! Unable to save report files: ", e));
		}
	}
	
	private void saveOneFile(ArrayList<SQResultsGroup> strategyResults) {
		SQResultsGroup sr = strategyResults.get(0);
		
		JFileChooser chooser = new JFileChooser();
		FileNameExtensionFilter filter = new FileNameExtensionFilter("SQ Strategy ", "str");
		
        chooser.setFileFilter(filter);
        chooser.setMultiSelectionEnabled(false);

        String dir = RecentFilesAndPaths.getPath(RecentFilesAndPaths.SAVE_STRATEGY);
        chooser.setCurrentDirectory(new File(dir));
    	
        String name = sr.getString("StrategyName");
        if(name == null) name = "StrategyName";
        
    	String fileName = dir+"/"+name + ".str";

    	File f = new File(fileName);
    	chooser.setSelectedFile(f);
        
        int returnVal = chooser.showSaveDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION && chooser.getSelectedFiles() != null) {
        	RecentFilesAndPaths.savePath(RecentFilesAndPaths.SAVE_STRATEGY, chooser.getCurrentDirectory().getAbsolutePath());
        	
        	boolean save = false;
        	
        	if(chooser.getSelectedFile().exists()) {
        		int ret = JOptionPane.showConfirmDialog(
        				MainApp.getFrame(),
        				L.t("The file with given name already exists, do you want to overwrite it?"),
        				L.t("Confirm file overwrite"),
        				JOptionPane.YES_NO_OPTION);

        		if (ret == JOptionPane.YES_OPTION) {
        			save = true;
        		}
        	} else {
        		save = true;
        	}
        	
        	if(save) {
        		try {
        			NewFileHandler.getInstance().saveResultToFile(sr, chooser.getSelectedFile().getAbsolutePath());
        		} catch (WriteAbortedException e) {
        			JOptionPane.showMessageDialog(MainApp.getFrame(),
        					String.format(L.t("Cannot write to '%s', it is write-protected. Try to save into another directory."), chooser.getCurrentDirectory().getAbsolutePath()),
        				    L.t("Access Denied"),
        				    JOptionPane.ERROR_MESSAGE);
        		} catch (Exception e) {
        			Log.error("Save strategy file failed. Exc.", e);
        			
        			JOptionPane.showMessageDialog(MainApp.getFrame(),
        					String.format(L.t("There was a problem saving the file '%s', error:")+": ", chooser.getSelectedFile().getAbsolutePath())+e.getMessage(),
        					L.t("Problem writing file"),
        				    JOptionPane.ERROR_MESSAGE);
        		}
        	}
        }
    }

	@Override
	public String getProduct() {
		return SQCoreConst.PRODUCT_SQ;
	}
	
	@Override
	public int getPreferredPosition() {
		return 1;
	}
}