/*
Version: 1.0, requires Writemonkey 2.5.0.8 or higher

Release date: August 25th 2013

Author: Josip

Description: 
Use "post it" style boxes to store snippets of text, images or links. Corkboards are stored in separate .board files but can be attached to individual text files or projects.

Installation:
Unzip the "Corkboards" directory into the plugins directory.

Deployment:
This plugin is initialized at startup. Right click blinds area (left or right of the main text) to call up the corkboards menu. Load hello.board (supplied with a plugin) for the tutorial.
*/

// Include some classes
monkey.include("_config.incl");
monkey.include("_config_user.incl");
monkey.include("json2.incl");
monkey.include("PostIt.incl");
monkey.include("PostItCollection.incl");
monkey.include("CorkboardCollection.incl");

// Set main singletons
var cc = new CorkboardCollection();
cc._init();
var pc = new PostItCollection();
pc._init();
// Attached files globals
attachedCollectionFile = "";
attachedCollectionProject = "";

// Board Number label
var boardNumberLabel = new System.Windows.Forms.Label();
boardNumberLabel.BackColor = System.Drawing.Color.Transparent;
boardNumberLabel.AutoSize = true;
boardNumberLabel.Font = new System.Drawing.Font("Arial", 20, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point);
boardNumberLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
boardNumberLabel.Text = "";
boardNumberLabel.Visible = false;
monkey.form.Controls.Add(boardNumberLabel);

// Main context menu
var mainMenu = new System.Windows.Forms.ContextMenuStrip();
mainMenu.ShowImageMargin = false;
mainMenu.ShowShortcutKeys = false;

mainMenu.add_Opened(function(object, eventargs) {
	checkAttachedFiles(monkey.fileHolder);
	checkIfClipboard();
	// disable previous & next if there is only one board in the collection
	if (cc.corkboardCollection.length <= 1) {
		nextBoardMenuItem.Enabled = false;
		prevBoardMenuItem.Enabled = false;
	} else {
		nextBoardMenuItem.Enabled = true;
		prevBoardMenuItem.Enabled = true;
	}
	cc.showBoardNumber();
});

var separator = new System.Windows.Forms.ToolStripSeparator();
var separator2 = new System.Windows.Forms.ToolStripSeparator();
var separator3 = new System.Windows.Forms.ToolStripSeparator();
var separator4 = new System.Windows.Forms.ToolStripSeparator();

var showHideMenuItem = new System.Windows.Forms.ToolStripMenuItem(SHOW_HIDE_S);
showHideMenuItem.add_Click(function(object, eventargs) {
	pc.toggleVisibility();
});

var newPostItMenuItem = new System.Windows.Forms.ToolStripMenuItem(NEW_ITEM_S);
newPostItMenuItem.add_Click(function(object, eventargs) {
	pc.createNew(true);
});

var pastePostItMenuItem = new System.Windows.Forms.ToolStripMenuItem(PASTE_ITEM_S);
pastePostItMenuItem.Visible = false;
pastePostItMenuItem.add_Click(function(object, eventargs) {
	pc.pasteCard();
});

var nextBoardMenuItem = new System.Windows.Forms.ToolStripMenuItem(NEXT_BOARD_S);
nextBoardMenuItem.add_Click(function(object, eventargs) {
	cc.toggleCollection(false);
});

var prevBoardMenuItem = new System.Windows.Forms.ToolStripMenuItem(PREV_BOARD_S);
prevBoardMenuItem.add_Click(function(object, eventargs) {
	cc.toggleCollection(true);
});

var newBoardMenuItem = new System.Windows.Forms.ToolStripMenuItem(NEW_BOARD_S);
newBoardMenuItem.add_Click(function(object, eventargs) {
	cc.setNewBoard();
});

var deleteBoardMenuItem = new System.Windows.Forms.ToolStripMenuItem(DELETE_BOARD_S);
deleteBoardMenuItem.add_Click(function(object, eventargs) {
	cc.deleteBoard();
});

var newCollectionMenuItem = new System.Windows.Forms.ToolStripMenuItem(NEW_COLLECTION_S);
newCollectionMenuItem.add_Click(function(object, eventargs) {
	cc.setNewCollection();
});

var loadCollectionMenuItem = new System.Windows.Forms.ToolStripMenuItem(LOAD_COLLECTION_S);
loadCollectionMenuItem.add_Click(function(object, eventargs) {
	cc.chooseExistingCollection();
});

var loadAttachedCollectionMenuItem = new System.Windows.Forms.ToolStripMenuItem(LOAD_ATTACHED_COLLECTION_S);
loadAttachedCollectionMenuItem.Visible = false;
loadAttachedCollectionMenuItem.add_Click(function(object, eventargs) {
	cc.saveLoadNew(attachedCollectionFile);
});

var loadAttachedCollectionMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(LOAD_ATTACHED_COLLECTION_S);
loadAttachedCollectionMenuItem2.Visible = false;
loadAttachedCollectionMenuItem2.add_Click(function(object, eventargs) {
	cc.saveLoadNew(attachedCollectionProject);
});

var createAttachedCollectionMenuItem = new System.Windows.Forms.ToolStripMenuItem(CREATE_FILE_ATTACHED_S);
createAttachedCollectionMenuItem.Visible = false;
createAttachedCollectionMenuItem.add_Click(function(object, eventargs) {
	cc.saveSetNew(getAttachedFileFileName(monkey.fileHolder));
});

var createAttachedCollectionMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(CREATE_PROJECT_ATTACHED_S);
createAttachedCollectionMenuItem2.Visible = false;
createAttachedCollectionMenuItem2.add_Click(function(object, eventargs) {
	cc.saveSetNew(getAttachedProjectFileName(monkey.fileHolder));
});

var autoArrangeMenuItem = new System.Windows.Forms.ToolStripMenuItem(AUTO_ARRANGE_S);
autoArrangeMenuItem.add_Click(function(object, eventargs) {
	pc.autoArrange();
});

mainMenu.Items.Add(showHideMenuItem);
mainMenu.Items.Add(separator);
mainMenu.Items.Add(nextBoardMenuItem);
mainMenu.Items.Add(prevBoardMenuItem);
mainMenu.Items.Add(separator2);
mainMenu.Items.Add(pastePostItMenuItem);
mainMenu.Items.Add(newPostItMenuItem);
mainMenu.Items.Add(newBoardMenuItem);
mainMenu.Items.Add(deleteBoardMenuItem);
mainMenu.Items.Add(newCollectionMenuItem);
mainMenu.Items.Add(loadCollectionMenuItem);
mainMenu.Items.Add(separator3);
mainMenu.Items.Add(loadAttachedCollectionMenuItem);
mainMenu.Items.Add(loadAttachedCollectionMenuItem2);
mainMenu.Items.Add(createAttachedCollectionMenuItem);
mainMenu.Items.Add(createAttachedCollectionMenuItem2);
mainMenu.Items.Add(separator4);
mainMenu.Items.Add(autoArrangeMenuItem);


monkey.form.ContextMenuStrip = mainMenu;


var timer1 = new System.Windows.Forms.Timer();
timer1.Interval = 100;
timer1.add_Tick(function(object, eventargs) {
	cc.hideBoardNumber();
});


// Shortcuts
// Entry point events / shortcut fired
monkey.add_extendedShortcutFiredE(function(object, eventargs) {
	if (eventargs.extendedKey == TOGGLE_VISIBILITY_KEY) {
		pc.toggleVisibility();
	} else if (eventargs.extendedKey == NEW_CARD_KEY) {
		pc.createNew(false);
	} else if (eventargs.extendedKey == NEXT_BOARD_KEY) {
		cc.toggleCollection(false);
	} else if (eventargs.extendedKey == PREVIOUS_BOARD_KEY) {
		cc.toggleCollection(true);
	} else if (eventargs.extendedKey == AUTO_ARRANGE_KEY) {
		pc.autoArrange();
	}
});


// Drag&drop
monkey.form.AllowDrop = true;

// From text to card
monkey.form.add_DragOver(function(object, eventargs) {
	if (eventargs.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text)) {
		// check if ctrl is pressed - move / copy
		if ((eventargs.KeyState & 8) == 8) {
			eventargs.Effect = System.Windows.Forms.DragDropEffects.Copy;
		} else {
			eventargs.Effect = System.Windows.Forms.DragDropEffects.Move;
		}
	}
});

monkey.form.add_DragDrop(function(object, eventargs) {
	try {
		pc.createNew(true, eventargs.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text));
	} catch (e) {
		// psst
	}
});


// From card to text
cardToTextFlag = false;
cardMoved = false;
mouseIsDown = false;
originalCardLocationX = 0;
originalCardLocationY = 0;

moveCard = function(p) {
	// remember initial position
	if (cardMoved == false && mouseIsDown) {
		originalCardLocationX = p.pluginForm.Location.X;
		originalCardLocationY = p.pluginForm.Location.Y;
		cardMoved = true;
	}

	if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Control || System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Shift) {
		cardToTextFlag = true;
		//p.setType("text", "");
		p.pluginForm.Opacity = 0.40;
		var point = new System.Drawing.Point(System.Windows.Forms.Cursor.Position.X, System.Windows.Forms.Cursor.Position.Y - 30);
		var charIndex = monkey.richTextBox.GetCharIndexFromPosition(monkey.richTextBox.PointToClient(point));
		monkey.select(charIndex, (charIndex - 1 >= monkey.richTextBox.Text.Length) ? 0 : 1);
	}
};


mouseUpCard = function(p) {
	if (cardToTextFlag && (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Control || System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Shift)) {
		var cardText = p.textBox.Text;
		if (System.Windows.Forms.Control.ModifierKeys != System.Windows.Forms.Keys.Shift) {
			p.removeItem(); // shift not pressed
		}
		// shift pressed / reposition
		else {
			p.pluginForm.SetBounds(originalCardLocationX, originalCardLocationY, p.pluginForm.Width, p.pluginForm.Height);
		}
		cardToTextFlag = false;
		monkey.select(monkey.selectionStart, 0);
		monkey.selectedText = cardText;
		monkey.performSyntaxColoring();
		monkey.richTextBox.Focus();
		monkey.select(monkey.selectionStart, 0);
		monkey.richTextBox.Refresh();
	}
	cardMoved = false;
};

// Save board upon exit
monkey.add_appClosingE(function(object, eventargs) {
	cc.saveBoardCollection();
	cc.saveUserData();
});

// Manage full screen / windowed
monkey.form.add_SizeChanged(function(object, eventargs) {
	if (pc.visible == false || HIDE_IN_WINDOWED_MODE == false) return;

	if (pc.visible == true && monkey.form.WindowState == System.Windows.Forms.FormWindowState.Normal) {
		pc.hideAll();
		pc.visible = true;
	} else if (pc.visible == true && monkey.form.WindowState == System.Windows.Forms.FormWindowState.Maximized) {
		pc.showAll();
	}
});

// Manage soft exit
monkey.form.add_VisibleChanged(function(object, eventargs) {
	if (pc.visible == true && monkey.form.Visible == false) {
		pc.hideAll();
		pc.visible = true;
	} else if (pc.visible == true && monkey.form.Visible == true) {
		pc.showAll();
	}
});

monkey.add_beforeOpenE(function(object, eventargs) {
	if (System.IO.Path.GetExtension(eventargs.beforeOpenFileHolder) == ".board") {
		eventargs.cancel = true;

		cc.saveBoardCollection(); // save
		cc.dispose(); // dispose
		pc.dispose();

		// set existing
		cc.corkboardCollectionFile = eventargs.beforeOpenFileHolder;
		cc.corkboardCollectionFileName = System.IO.Path.GetFileNameWithoutExtension(eventargs.beforeOpenFileHolder);

		cc.loadBoardCollection();
		cc.setBoard();
		pc.showAll();

		return eventargs;
	}

	// Check for attached board and open it automatically
	try {
		var attached = getAttachedFiles(eventargs.beforeOpenFileHolder)[0];
		if (AUTO_LOAD_ATTACHED_BOARD && attached != null) {
			if (attached != cc.corkboardCollectionFile) { // open only if not already opened
				cc.saveLoadNew(attached);
			}
		}
	} catch (e) {
		// psst
	}
});


checkAttachedFiles = function(filePath) {
	loadAttachedCollectionMenuItem.Visible = false;
	loadAttachedCollectionMenuItem2.Visible = false;
	createAttachedCollectionMenuItem.Visible = false;
	createAttachedCollectionMenuItem2.Visible = false;
	separator3.Visible = false;

	if (filePath == "-1") // return if in Scratch mode 
		return;

	var attachedFiles = getAttachedFiles(filePath);
	separator3.Visible = true;
	// handle attached to file
	if (attachedFiles[0] != null) {
		loadAttachedCollectionMenuItem.Visible = true;
		loadAttachedCollectionMenuItem.Text = LOAD_ATTACHED_COLLECTION_S + System.IO.Path.GetFileName(attachedFiles[0]);
		attachedCollectionFile = attachedFiles[0];
		if (attachedFiles[0] == cc.corkboardCollectionFile) {
			loadAttachedCollectionMenuItem.Enabled = false;
		} else {
			loadAttachedCollectionMenuItem.Enabled = true;
		}
	} else {
		createAttachedCollectionMenuItem.Visible = true;
		createAttachedCollectionMenuItem.Text = CREATE_FILE_ATTACHED_S;
		attachedCollectionFile = "";
	}
	// handle attached to project
	if (attachedFiles[1] != null) {
		loadAttachedCollectionMenuItem2.Visible = true;
		loadAttachedCollectionMenuItem2.Text = LOAD_ATTACHED_COLLECTION_S + System.IO.Path.GetFileName(attachedFiles[1]);
		attachedCollectionProject = attachedFiles[1];
		if (attachedFiles[1] == cc.corkboardCollectionFile) {
			loadAttachedCollectionMenuItem2.Enabled = false;
		} else {
			loadAttachedCollectionMenuItem2.Enabled = true;
		}
	} else {
		createAttachedCollectionMenuItem2.Visible = true;
		createAttachedCollectionMenuItem2.Text = CREATE_PROJECT_ATTACHED_S;
		attachedCollectionProject = "";
	}
};

checkIfClipboard = function() {
	if (System.Windows.Forms.Clipboard.ContainsData("wm_board")) {
		pastePostItMenuItem.Visible = true;
		pastePostItMenuItem.Text = PASTE_ITEM_S;
	} else if (System.Windows.Forms.Clipboard.ContainsText()) {
		pastePostItMenuItem.Visible = true;
		pastePostItMenuItem.Text = PASTE_TEXT_AS_CARD_S;
	} else {
		pastePostItMenuItem.Visible = false;
	}
};



getAttachedFiles = function(filePath) {

	var attachedToFile = getAttachedFileFileName(filePath);
	var attachedToProject = getAttachedProjectFileName(filePath);

	var attachedFiles = [];
	if (System.IO.File.Exists(attachedToFile)) { // check if there is a board attached to a file 
		attachedFiles[0] = attachedToFile;
	}
	if (System.IO.File.Exists(attachedToProject)) { // check if there is a board attached to a project
		attachedFiles[1] = attachedToProject;
	}
	return attachedFiles;
};

getAttachedFileFileName = function(filePath) {
	return System.IO.Path.ChangeExtension(filePath, "board");
};

getAttachedProjectFileName = function(filePath) {
	var dirInfo = new System.IO.DirectoryInfo(System.IO.Path.GetDirectoryName(filePath));
	var dirPath = dirInfo.FullName;
	var dirName = dirInfo.Name;
	return dirPath + "\\" + dirName + ".board";
};


monkey.add_beforeSaveE(function(object, eventargs) {
	if (SAVE_WITH_TEXT && !monkey.richTextBox.isAutoSave) {
		cc.saveBoardCollection();
		cc.saveUserData();
	}
});


getColorFromName = function(colorName, isInkColor) {
	// handle hex values
	if (colorName.indexOf("#") == 0) {
		return System.Drawing.ColorTranslator.FromHtml(colorName);
	}
	switch (colorName) {
		case "Paper":
			return monkey.paperColor;
		case "Ink":
			return monkey.inkColor;
		case "Dimmed":
			return monkey.dimmedColor;
		case "Default":
			return (isInkColor) ? monkey.paperColor : monkey.dimmedColor;
		default:
			// handle color names
			return System.Drawing.Color.FromName(colorName);
	}
};


// *************** Entry point *************** //


// // Background on secondary monitor 

// var backForm = monkey.getBlankPluginForm(0, 0);
// backForm.Visible = false;

// isValidScreen = function() {
// 	if (SECONDARY_MONITOR > 0 &&
// 		SECONDARY_MONITOR <= System.Windows.Forms.Screen.AllScreens.Length &&
// 		System.Windows.Forms.Screen.AllScreens[SECONDARY_MONITOR - 1] != System.Windows.Forms.Screen.FromControl(monkey.form)) {
// 		return true;
// 	} else {
// 		return false;
// 	}
// };

// if (isValidScreen()) {
// 	var screens = System.Windows.Forms.Screen.AllScreens;
// 	backForm.BackColor = getColorFromName(SECONDARY_MONITOR_BACKGROUND_COLOR);
// 	backForm.softClose = true;
// 	backForm.deactivatedOpacity = 1;
// 	backForm.showMinimizeButton = false;
// 	backForm.roundedCorners = 1;
// 	backForm.allowResize = false;
// 	backForm.allowMove = false;
// 	backForm.AllowDrop = true;
// 	backForm.Left = screens[SECONDARY_MONITOR - 1].Bounds.Left;
// 	backForm.Top = screens[SECONDARY_MONITOR - 1].Bounds.Top;
// 	backForm.Width = screens[SECONDARY_MONITOR - 1].Bounds.Width;
// 	backForm.Height = screens[SECONDARY_MONITOR - 1].Bounds.Height;
// 	backForm.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
// 	backForm.SendToBack();
// 	//backForm.contextMenu = mainMenu;
// }

// showBack = function() {
// 	if (isValidScreen()) {
// 		backForm.Visible = true;
// 		backForm.Enabled = false;
// 	}
// };

// hideBack = function() {
// 	backForm.Visible = false;
// };

// backForm.add_DragOver(function(object, eventargs) {
// 	if (eventargs.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text)) {
// 		// check if ctrl is pressed - move / copy
// 		if ((eventargs.KeyState & 8) == 8) {
// 			eventargs.Effect = System.Windows.Forms.DragDropEffects.Copy;
// 		} else {
// 			eventargs.Effect = System.Windows.Forms.DragDropEffects.Move;
// 		}
// 	}
// });

// backForm.add_DragDrop(function(object, eventargs) {
// 	try {
// 		pc.createNew(true, eventargs.Data.GetDataPresent(System.Windows.Forms.DataFormats.Text));
// 	} catch (e) {
// 		// psst
// 	}
// });



var boardFileToLoad;
if (!System.IO.File.Exists(USER_DATA_FILE_PATH)) { // Probably first time user, show hello.board
	boardFileToLoad = monkey.pluginDirectoryPath + "/hello.board";
} else {
	var pluginUserDataJson = System.IO.File.ReadAllText(USER_DATA_FILE_PATH, System.Text.Encoding.UTF8);
	var pluginUserDataObject = JSON.parse(pluginUserDataJson);

	if (System.IO.File.Exists(pluginUserDataObject.lastBoard)) { // Load board
		boardFileToLoad = pluginUserDataObject.lastBoard;
	} else { // Set fail board
		boardFileToLoad = monkey.pluginDirectoryPath + "/fail.board";
	}
}
cc.corkboardCollectionFile = boardFileToLoad;
cc.corkboardCollectionFileName = System.IO.Path.GetFileNameWithoutExtension(cc.corkboardCollectionFile);

// Load file
cc.loadBoardCollection();
cc.setBoard();
if (SHOW_ON_STARTUP) pc.showAll();