// GoogleカレンダーへMextractrの結果を登録するためのクラス
// 処理の切り分けが甘いので今後リファクタを行うこと。

(function(){

// jqueryの別名。	
var j$ = jQuery;
	

// namespace
// TODO: 関数化する
if(!metal.thirdparty) metal.thirdparty = {}
if(!metal.thirdparty.google) metal.thirdparty.google = {}

metal.thirdparty.google.Calendar = function(){

	//properties
	this.json_url = "../accelerator/json";
	
	//Mextractr結果の辞書
	//要リファクタ。
	this.mextracted_dic = new Object();
}

//Mextractrサーバへ通信した結果のJSONを解析してGoogleカレンダー形式で登録するURLを取得する。
//TODO: 名前をリファクタすること
metal.thirdparty.google.Calendar.prototype.connect = function(text, callback){
	var self = this;

　　// Mextractrを実行して結果を受取る
  j$.ajax({
    url: this.json_url,
    data: { "text": text },
    success: function(data, status) {
		callback(self.create_url(data, text));
	}
  });	
}	

metal.thirdparty.google.Calendar.prototype.create_mextracted_dic = function(mextracteds){

	var mextracted_dic = new Object
	var len = mextracteds.length;
	for (i = 0; i < len; ++i) {
		mextracted = mextracteds[i];
		if(mextracted_dic[mextracted.type] == undefined){
			mextracted_dic[mextracted.type] = new Array();
		}
		
		mextracted_dic[mextracted.type].push(mextracted);
	};
	return mextracted_dic;
}

metal.thirdparty.google.Calendar.prototype.analyze = function(json){
	// eval して各項目にアクセス
	var mList = eval('(' + json + ')');
	this.mextracted_dic = this.create_mextracted_dic(mList);
}


metal.thirdparty.google.Calendar.prototype.each_mextracteds = function(typename, callback){
	mextracteds = this.mextracted_dic[typename];
	if(mextracteds != undefined){
		for(var i = 0; i < mextracteds.length; ++i){
			callback(mextracteds[i])			
		}
	}
}



//Mextractrの結果JSONから標準的なURLを作成する
metal.thirdparty.google.Calendar.prototype.create_url = function(json, org_text){
	
	this.analyze(json);

	var eventname = "";
	var who = "";
	var when = "";
	var whens = "";
	var where = "";
	var location = "";
	var facility = "";
	
	this.each_mextracteds('event', function(mextracted){
	  if( eventname == "" ){
        eventname = mextracted.content;
	  } else {
        eventname = eventname + " / " + mextracted.content;
      };
	});
	
	this.each_mextracteds('org_name', function(mextracted){
	  who = who + "ORG: " + mextracted.content + "\n";
	});
	
	this.each_mextracteds('name', function(mextracted){
	  who = who + "WHO: " + mextracted.content + "\n";
	});
	
	this.each_mextracteds('address', function(mextracted){
	  if(location == ""){
	      location = mextracted.content;
	    }
        where = where + "WHERE: " + mextracted.content + "\n";
	});
	
	this.each_mextracteds('facility', function(mextracted){
	  facility = facility + "WHERE: " +  mextracted.content + "\n";
	});

	var self = this;
	this.each_mextracteds('datetime', function(mextracted){
	   // 最初に見つかったdatetimeを有効とする
       if(when == "") {
	   		when = self.create_google_date_strings(mextracted);
		}
	});

  
	if( when=="" ){ // 上記の処理後でもwhenがなければ　今の時刻を持つ
		when = this.create_google_now_strings();
	}
	
	return this.build_url_from_5w(when, where, location, who, eventname, facility, org_text);

}

//現在時刻を示すGoogleカレンダー形式の文字列を取得する
metal.thirdparty.google.Calendar.prototype.create_google_now_strings = function(){
	var nowdate = new Date();
	var now = this.to_google_date_string(nowdate);
	return now + "/" + now;
}

//datetimeのmextractedからGoogleCalendar形式の文字列を作成する。
metal.thirdparty.google.Calendar.prototype.create_google_date_strings = function(mextracted){
	var when = "";
	var adjusted = "";
	if( mextracted.startTimeAll.indexOf("T",0) == -1 ) {
	 // startTimeAll に Tが入ってない = 日付 2008-12-01　形式なので 「-」 を抜く
	 tmp = mextracted.startTimeAll.replace("-","");
	 adjusted = tmp.replace("-","");
	} else {
	 // そのままgoogleカレンダー呼び出しに使える形式
	 adjusted = mextracted.startTimeAll;
	};
	
	when = adjusted;
	if(mextracted.endTimeAll != undefined) {
		// endTimeあり
		if( mextracted.endTimeAll.indexOf("T",0) == -1 ) {
		 // endTime に Tが入ってない = 日付 2008-12-01　形式なので 「-」 を抜く
		 // startDate +1 をendDateとする 2009-03-13 googleの仕様変更に追従のため追記
		 //   tmp = mextracted.endTimeAll.replace("-","");
		 //   adjusted = tmp.replace("-","")
		  dArr = new Array()
		  dArr = mextracted.endTimeAll.split("-");
		  aDate = new Date(dArr[0], dArr[1] -1, dArr[2])
		  baseSec = aDate.getTime();
		  addSec = 86400000; //1日のミリ秒数
		  endSec = baseSec + addSec;
		  aDate.setTime(endSec);
		  mon_s = "" + (aDate.getMonth() + 1);
		  if ( mon_s.length < 2 ) { mon_s = "0" + mon_s  };
		  date_s = "" + aDate.getDate();
		  if ( date_s.length < 2 ) { date_s = "0" + date_s  };
		  adjusted = "" + aDate.getFullYear() + mon_s + date_s;
		} else {
		  adjusted = mextracted.endTimeAll;
		};
		when = when + "/" + adjusted;
		} else {
		// endTimeなし
		if ( when.length > 8 ) {
		  when = when + "/" + when;
		} else {
		  // 日付だけでendなし、そのままだとカレンダ登録でエラーになる 2009-02-26 以下は回避策
		  // 対策１　朝７時から8時と仮定する
		  // when = when + "T220000Z/" + when + "T230000Z"
		  // 対策２　今後ずっとこの仕様だったときのために　startDate +1 をendDateとする
		  dArr = new Array()
		  dArr = mextracted.startTimeAll.split("-");
		  aDate = new Date(dArr[0], dArr[1] -1, dArr[2])
		  baseSec = aDate.getTime();
		  addSec = 86400000; //1日のミリ秒数
		  endSec = baseSec + addSec;
		  aDate.setTime(endSec);
		  mon_s = "" + (aDate.getMonth() + 1);
		  if ( mon_s.length < 2 ) { mon_s = "0" + mon_s  };
		  date_s = "" + aDate.getDate();
		  if ( date_s.length < 2 ) { date_s = "0" + date_s  };
		  endDateStr = "" + aDate.getFullYear() + mon_s + date_s;
		  when = when + "/" + endDateStr;
		}
	}
	
	return when;
}


metal.thirdparty.google.Calendar.prototype.build_url_from_5w = function(when, where, location, who, eventname, facility, org_text){
  var dates = when;
  var details = who + "\n" + where + "\n" + facility;
  return this.build_url(eventname, dates, details, location);
}



//GoogleCalender形式の文字列をDate型から取得する。
metal.thirdparty.google.Calendar.prototype.to_google_date_string = function(nowdate){
	
    var year = nowdate.getFullYear(); // 年 
    var mon  = nowdate.getMonth() + 1; // 月 
    mon_s = String(mon);
    if ( mon_s.length < 2 ) { mon_s = "0" + mon_s  };
    var date = nowdate.getDate(); // 日 
    var hour = nowdate.getHours(); // 時
    if ( hour > 9 ) {
      hour = Number(hour) - 9;
    } else {
       date = date - 1;
       hour = 24 + Number(hour) - 9;
    };

    date_s = String(date);
    if ( date_s.length < 2 ) { date_s = "0" + date_s  };
    hour_s = String(hour);
    if ( hour_s.length < 2 ) { hour_s = "0" + hour_s };

    var min  = nowdate.getMinutes(); // 分 
    min_s = String(min);
    if ( min_s.length < 2 ) { min_s = "0" + min_s };
    var sec  = nowdate.getSeconds(); // 秒 
    sec_s = String(sec);
    if ( sec_s.length < 2 ) { sec_s = "0" + sec_s };
    return "" + year + mon_s + date_s + "T" + hour_s + min_s + sec_s + "Z" ;	
}

metal.thirdparty.google.Calendar.prototype.to_google_date_strings = function(start_date, end_date){
	return this.to_google_date_string(start_date) + '/' + this.to_google_date_string(end_date);
}

var gc_url = 'http://www.google.com/calendar/event';

//GoogleCalenderのUIを取得できるURLを作成する
metal.thirdparty.google.Calendar.prototype.build_url = function(text, dates, details, location){

  var escape = encodeURI;

  //URL生成
  var url = gc_url + "?action=TEMPLATE";
  url += "&text=" + escape(text);
  url += "&dates=" + escape(dates);
  url += "&details=" + escape(details);
  url += "&location=" + escape(location);
  url += "&trp=false&sprop=&sprop=name:";
  
  return url;
}


metal.thirdparty.google.Calendar.prototype.build_form = function(text, dates, details, location){
  
  var f = document.createElement('form');
  
  metal.util.form.create_input(f, 'text', text);
  metal.util.form.create_input(f, 'dates', dates);
  metal.util.form.create_input(f, 'details', details);
  metal.util.form.create_input(f, 'location', location);
  metal.util.form.create_input(f, 'action', 'TEMPLATE');
  metal.util.form.create_input(f, 'trp', 'false');
  metal.util.form.create_input(f, 'sprop', '');

  f.action = gc_url;
  
  return f;
}
	
})()






