using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using System.Text;
// The 'text' parameter will contain the text from the:
//   - Current Clipboard when run by HotKey
//   - History Item when run from the History Menu
// The returned string will be:
//   - Placed directly on the Clipboard
//   - Ignored by ClipboardFusion if it is 'null'
public static class ClipboardFusionHelper
{
	public static string ProcessText(string text)
	{
        //open a "cfitems" file
        string filename = "";
        using(OpenFileDialog dialog = new OpenFileDialog())
        {
            dialog.Filter = "ClipboardFusion Item List|*.cfitems";
            dialog.Multiselect = false;
            if(dialog.ShowDialog() != DialogResult.OK)
                return null;
                
            filename = dialog.FileName;
        }
	
        //parse the file
        List<ClipboardItem> items = new List<ClipboardItem>();
        using(FileStream file = File.OpenRead(filename))
        using(StreamReader reader = new StreamReader(file))
        {
            ClipboardItemParserStateEnum state = ClipboardItemParserStateEnum.Text;
            ClipboardItem item = null;
            while(true)
            {
                string line = reader.ReadLine();
                if(line == null)
                    break;
                    
                if(item == null)
                    item = new ClipboardItem();
                    
                switch(state)
                {                        
                    case ClipboardItemParserStateEnum.Text:
                        if(line.Length > 0)                        
                            item.Text = Encoding.Unicode.GetString(Convert.FromBase64String(line));                            
                        
                        break;
                    case ClipboardItemParserStateEnum.Image:
                        if(line.Length > 0) 
                        {
                            using(MemoryStream stream = new MemoryStream(Convert.FromBase64String(line)))
                                item.Image = new Bitmap(stream);
                        }
                    
                        break;
                    case ClipboardItemParserStateEnum.Files:
                        if(line.Length > 0) 
                            item.Files = Encoding.Unicode.GetString(Convert.FromBase64String(line)).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);
                        
                        //add the item to the list
                        items.Add(item);
                        item = null;
                        break;
                }
                
                
                //increment the state
                state = (ClipboardItemParserStateEnum)(((int)state + 1) % 3);
            }
        }
	
        using(FormImport form = new FormImport(items))
            Application.Run(form);
	
		// your code goes here
		return null;
	}
	
	private enum ClipboardItemParserStateEnum
	{
        Text = 0,
        Image = 1,
        Files = 2,
	}
	
	private class ClipboardItem
	{
        public string Text {get;set;}
        public Bitmap Image {get;set;}
        public string[] Files {get;set;}
        
        public ClipboardItem()
        {
            this.Text = "";
            this.Image = null;
            this.Files = new string[0];
        }
        
        public ListViewItem ToListViewItem()
        {
            ListViewItem item = new ListViewItem(this.Text);
            item.SubItems.Add( (this.Image == null) ? "No" : "Yes" );
            item.SubItems.Add( string.Join(", ", this.Files) );
            item.Tag = this;
            return item;
        }
	}
	
	private class FormImport : Form
	{
        private ComboBox cboLists;
		private ListView lvItems;
		private ColumnHeader colText;
		private ColumnHeader colImage;
		private ColumnHeader colFiles;
		private Button btnImport;
		
		public FormImport(List<ClipboardItem> items)
		{
            this.cboLists = new ComboBox();
			this.lvItems = new ListView();
			this.btnImport = new Button();
			this.colText = new ColumnHeader();
			this.colImage = new ColumnHeader();
			this.colFiles = new ColumnHeader();
		
            this.SuspendLayout();
            
            this.colText.Text = "Text";
            this.colText.Width =  140;
            this.colImage.Text = "Has Image";
            this.colFiles.Text = "Files";
            
            this.cboLists.DropDownStyle = ComboBoxStyle.DropDownList;
            this.cboLists.Location = new Point(16, 16);
            this.cboLists.Size = new Size(296, 21);
            this.cboLists.Items.AddRange(new string[]{"History", "Local Pinned", "Recent Online", "Pinned Online"});
            this.cboLists.SelectedIndex = 0;
            
            this.lvItems.Columns.AddRange(new ColumnHeader[] { this.colText, this.colImage, this.colFiles });
            this.lvItems.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            this.lvItems.Location = new Point(16, 48);
            this.lvItems.Size = new Size(296, 336);
            this.lvItems.View = View.Details;            
            this.lvItems.FullRowSelect = true;
            foreach(ClipboardItem item in items)
                this.lvItems.Items.Add(item.ToListViewItem());
            
            this.btnImport.Click += this.btnImport_Click;
            this.btnImport.Text = "Import Selected Items to Selected List";
            this.btnImport.Location = new Point(16, 392);
            this.btnImport.Size = new Size(296, 32);
            
            this.ClientSize = new System.Drawing.Size(329, 439);
            this.Controls.Add(this.btnImport);
            this.Controls.Add(this.lvItems);
            this.Controls.Add(this.cboLists);
            this.Text = "ClipboardFusion Item Importer";
           
            this.ResumeLayout(false);
		}
		
		private void btnImport_Click(object sender, EventArgs e)
		{
            string value = this.cboLists.SelectedItem as string;  
            foreach(ListViewItem lvItem in this.lvItems.SelectedItems)
            {
                ClipboardItem item = lvItem.Tag as ClipboardItem;
                if(item == null)
                    continue;
            
                switch(value)
                {
                    case "History":
                        {
                            BFS.ClipboardFusion.AddHistoryText(item.Text);
                            int index = BFS.ClipboardFusion.GetHistoryItemCount() - 1;
                            BFS.ClipboardFusion.SetHistoryImage(index, item.Image);
                            BFS.ClipboardFusion.SetHistoryFileList(index, item.Files);
                        }
                        
                        break;       
                    case "Local Pinned":
                        {
                            BFS.ClipboardFusion.AddLocalPinnedText(item.Text);
                            int index = BFS.ClipboardFusion.GetLocalPinnedItemCount() - 1;
                            BFS.ClipboardFusion.SetLocalPinnedImage(index, item.Image);
                            BFS.ClipboardFusion.SetLocalPinnedFileList(index, item.Files);
                        }
                        
                        break;                           
                    case "Recent Online":
                        BFS.ClipboardFusion.CFOSaveText(item.Text);
                    
                        break;   
                    case "Pinned Online":
                        BFS.ClipboardFusion.CFOSavePinnedText(item.Text);
                    
                        break;            
                }
            }
            
            BFS.Dialog.ShowMessageInfo("Clipboard Items have been added to the " + value + " Items list");
            this.Close();
		}
	}
}