using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace OPlanner {

	public delegate void ObjectChangedEventHandler(OBaseObject obj);

	public partial class ObjectsPanel : UserControl {

		public ObjectsPanel() {
			InitializeComponent();
		}

		private OCurrentInfo info;

		public void SetInfo(OCurrentInfo newInfo) {
			info = newInfo;
			info.DataLoaded += new BasicEventHandler(DataLoadedHandler);
			info.ObjectsSelected += new SenderEventHandler(ObjectsSelectedHandler);
			info.ObjectsDeselected += new SenderEventHandler(ObjectsSelectedHandler);
			info.ObjectsCreated += new SenderEventHandler(ObjectsCreatedHandler);
			info.ObjectsDeleted += new SenderEventHandler(ObjectsCreatedHandler);
			info.ObjectsUpdated += new UpdateEventHandler(UpdateObjectsHandler);
		}

		private void DataLoadedHandler() {
			LoadData();
		}

		private void ObjectsSelectedHandler(object sender) {
			UpdateSelectedObjects();
		}

		private void UpdateObjectsHandler(object sender, UpdateType updateType, List<OBaseObject> objects, bool updatePropertiesPanel) {
			if (updatePropertiesPanel == false) {
				return;
			}
			UpdateObjects();
		}

		private void ObjectsCreatedHandler(object sender) {
			UpdateObjects();
		}

		public void LoadData() {
			ClearObjectsBox();
			if (info.Data == null) {
				return;
			}
			UpdateObjects();
		}

		private List<OBaseObject> GetSelectedObjects() {
			List<OBaseObject> list = new List<OBaseObject>();
			IList objects = objectsBox.SelectedItems;
			for (int i = 0; i < objects.Count; i++) {
				OBaseObject obj = (OBaseObject)((CustomListBoxItem)objects[i]).ObjectData;
				if (obj != null) {
					list.Add(obj);
				}
			}
			return list;
		}

		private void UpdateSelectedObjects() {
			objectsBox.SelectionChanged -= new SelectionChangedEventHandler(objectsBox_SelectionChanged);
			objectsBox.SelectedItems.Clear();
			for (int i = 0; i < info.SelectedObjects.Count; i++) {
				for (int j = 0; j < objectsBox.Items.Count; j++) {
					OBaseObject obj = (OBaseObject)((CustomListBoxItem)objectsBox.Items[j]).ObjectData;
					if (info.SelectedObjects[i].MatchesObject(obj)) {
						objectsBox.SelectedItems.Add(objectsBox.Items[j]);
					}
				}
			}
			objectsBox.SelectionChanged += new SelectionChangedEventHandler(objectsBox_SelectionChanged);
		}

		private void ClearObjectsBox() {
			objectsBox.SelectionChanged -= new SelectionChangedEventHandler(objectsBox_SelectionChanged);
			objectsBox.Items.Clear();
			objectsBox.SelectedIndex = -1;
			objectsBox.SelectionChanged += new SelectionChangedEventHandler(objectsBox_SelectionChanged);
		}

		private void DeleteSelectedObjects() {
			List<OBaseObject> objects = GetSelectedObjects();
			if (objects.Count == 0) {
				return;
			}
			info.SelectedObjects.Clear();
			info.InvokeObjectsDeselected(this);
			info.InvokeDataChanging(this, "Delete Objects");
			info.Data.RemoveObjects(objects);
			info.InvokeDataChanged(this, "Delete Objects");
			info.InvokeObjectsDeleted(this);
		}

		private void deleteButton_Click(object sender, RoutedEventArgs e) {
			DeleteSelectedObjects();
		}

		private void UpdateObjects() {
			ClearObjectsBox();
			List<OBaseObject> tempList = new List<OBaseObject>(info.Data.OObjects);
			tempList.Sort(OPlannerHelper.CompareOBaseObjects);
			for (int i = 0; i < tempList.Count; i++) {
				objectsBox.Items.Add(new CustomListBoxItem(tempList[i].GetRepresentation(), tempList[i]));
			}
			UpdateSelectedObjects();
		}

		private void ObjectDoubleClickHandler(object sender, MouseButtonEventArgs e) {
			OBaseObject obj = (OBaseObject)((CustomListBoxItem)sender).ObjectData;
			if (info.SelectedCourse == null || obj == null) {
				return;
			}
			info.InvokeDataChanging(this, "Add Course Object");
			info.SelectedCourse.AddObjectRef(obj);
			info.InvokeDataChanged(this, "Add Course Object");
			info.InvokeObjectsCreated(this);
		}

		private void objectsBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
			info.SelectedObjects.Clear();
			List<OBaseObject> list = GetSelectedObjects();
			info.SelectedObjects = list;
			info.InvokeObjectsSelected(this);
		}

		private void objectsBox_KeyDown(object sender, KeyEventArgs e) {
			if (e.Key == Key.Delete) {
				DeleteSelectedObjects();
			}
		}

	}

}
