using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Google.GData.Client;
using Google.Documents;
using System.Windows.Forms;
using System.IO;
using CaLib.User;
using ClipClop.User;


namespace ClipClop.Model
{
	public class GData
	{
		bool bLogin_ = false;

		GDataCredentials credentials_;
		RequestSettings settings_;
		DocumentsRequest request_;

		Exception exp_;

		List<Document> googleDocuments_ = new List<Document>();

		public int TargetIndex { set; get; }

		string tempFilePath_ = null;
		public string TempFilePath
		{
			get
			{
				return tempFilePath_;
			}
		}

		public GData()
		{
		}

		public bool IsLogin
		{
			get { return bLogin_; }
		}

		public int Count
		{
			get
			{
				return googleDocuments_.Count;
			}
		}

		public Exception Excep
		{
			get
			{
				return exp_;
			}
		}

		public void SetCredentials(string username, string password)
		{
			credentials_ = new GDataCredentials(username, password);
		}

		public void Logoff()
		{
			//TODO これでいいのか知らない
			credentials_ = null;
			settings_ = null;
			request_ = null;

			bLogin_ = false;
		}

		public void Login()
		{
			bLogin_ = false;
			exp_ = null;

			try
			{
				settings_ = new RequestSettings(Application.ProductName, credentials_);
				settings_.AutoPaging = true;
				settings_.PageSize = 100;

				//どこかで例外がでるかも、が継続できる

				request_ = new DocumentsRequest(settings_);

				bLogin_ = true;

				UpdateDocumentsList();
			}
			catch (Exception exp)
			{
				exp_ = exp;
			}
		}

		private void UpdateDocumentsList()
		{
			TargetIndex = -1;

			Feed<Document> feed = request_.GetEverything();

			if (feed == null || feed.Entries == null)
			{
				return;
			}

			// this takes care of paging the results in
			foreach (Document entry in feed.Entries)
			{
				//all.Add(entry);

				if (entry.Type == Document.DocumentType.Folder)
				{
					continue;
				}
				googleDocuments_.Add(entry);
			}
		}

		public string[] GetDocumentInfo(int index)
		{
			string[] s = new string[3];

			//名前,種別,フォルダ
			s[0] = googleDocuments_[index].Title;
			s[1] = googleDocuments_[index].Type.ToString();
			s[2] = "";//TODO フォルダー対応する

			return s;
		}

		public bool IsDownloadable(int index)
		{
			//XMLファイルはunknownになるらしい
			return googleDocuments_[index].Type == Document.DocumentType.Unknown;
		}

		public void DeleteTempFile()
		{
			try
			{
				if (!string.IsNullOrEmpty(this.tempFilePath_))
				{
					File.Delete(this.tempFilePath_);
				}
			}
			catch
			{
			}
			finally
			{
				tempFilePath_ = string.Empty;
			}
		}

		public void Import()
		{
			DeleteTempFile();
			exp_ = null;

			if (TargetIndex < 0 || googleDocuments_.Count <= TargetIndex)
			{
				exp_ = new FundamentalException(ClipClop.Properties.Resources.EA001);
				return;
			}

			Document entry = googleDocuments_[this.TargetIndex];

			try
			{

				String queryUri = entry.DocumentEntry.Content.Src.ToString();
				Uri target = new Uri(queryUri);

				tempFilePath_ = Path.GetTempFileName();

				using (FileStream outFile = new FileStream(tempFilePath_, FileMode.Create, FileAccess.Write))
				{
					using (Stream stream = request_.Service.Query(target))
					{
						int nBytes = 8192;
						Byte[] arr = new Byte[nBytes];

						int bytesRead;
						while ((bytesRead = stream.Read(arr, 0, arr.Length)) > 0)
						{
							outFile.Write(arr, 0, bytesRead);
						}
						stream.Close();
					}
					outFile.Close();
				}

				//読み込めるか確認する
				XmlContextMenuReader reader = new XmlContextMenuReader();
				reader.Read(tempFilePath_);
			}
			catch (Exception exp)
			{
				exp_ = exp;
				DeleteTempFile();
				return;
			}
		}

		/// <summary>
		/// ファイル一覧作成処理がこれでいいのか確認してないけど、期待通りの結果になった。
		/// </summary>
		public void Refresh()
		{
			DeleteTempFile();
			exp_ = null;
			googleDocuments_.Clear();

			try
			{
				UpdateDocumentsList();
			}
			catch (Exception exp)
			{
				exp_ = exp;
			}
		}



	}
}
