// JavaScript Document

var SearchManagerConfig = {
	DEFAULT_RESULT_NUM			:30,
	DEFAULT_KEYWORD_NUM			:50,
	DEFAULT_BOOK_DRILL_NUM		:10,
	DEFAULT_WORK_DRILL_NUM		:40,
	DEFAULT_CREATOR_DRILL_NUM	:10,
	DEFAULT_WIKIPEDIA_NUM		:10,
	
	MATCH_DETAIL_BOOK_NUM		:9,
	MATCH_DETAIL_WORK_NUM		:2,
	MATCH_DETAIL_CREATOR_NUM	:5
}


//function which manages search
var SearchManager = {
	moreResultObj	:null,
	resultObj		:null,
	conditionObj	:null,
	keyword :"",
	matchDetailArr	:null,
	order :null,
	searchPath		:"",
	assocType		:null,
	errorMessage	:"",
	//drilldowns		:new Array(),
	xhr				:null,
	
	resultNum:30,
	
	MAX_ASSOC_RESULT_NUM:50,
	
	METHOD	:'POST',
	TIMEOUT	:120000,
	
	//search from text
	assocTextSearch:function(text){
		if(!text || text == ""){
			SearchManager.errorMessage = "検索テキストが含まれていません。";
			Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
			return;
		}
		this.assocType = AssocType.TEXT;
		
		var option = {
			text:text,
			start_num:0,
			keywords_num:SearchManagerConfig.DEFAULT_KEYWORD_NUM,
			wikipedia_num:SearchManagerConfig.DEFAULT_WIKIPEDIA_NUM
		};
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_ASSOC_TEXT_PATH;
		
		this._assocSearch(false);
	},
	
	//search from shelf
	assocShelfSearch:function(shelfId){
		var savedId = CookieManager.getShelfSavedId();
		if(!shelfId || !savedId) return;
		this.assocType = AssocType.SHELF;
		
		var option = {
			shelf_id:shelfId,
			start_num:0,
			keywords_num:SearchManagerConfig.DEFAULT_KEYWORD_NUM,
			wikipedia_num:SearchManagerConfig.DEFAULT_WIKIPEDIA_NUM
		};

        if (CookieManager.isMember()) {
            option.openid = savedId;
        } else {
            option.saved_id = savedId;
        }

		this.conditionObj = option;
		this.searchPath = FixedValues.API_ASSOC_SHELF_PATH;
		
		this._assocSearch(false);
	},
	
	//search from wikipedia
	assocWikiSearch:function(wikiId){
		if(!wikiId) return;
		this.assocType = AssocType.WIKIPEDIA;
		
		var option = {
			wikipedia_id:wikiId,
			start_num:0,
			keywords_num:SearchManagerConfig.DEFAULT_KEYWORD_NUM,
			wikipedia_num:SearchManagerConfig.DEFAULT_WIKIPEDIA_NUM
		};
		this.conditionObj = option;
		this.searchPath = FixedValues.API_ASSOC_WIKI_PATH;
		
		this._assocSearch(false);
	},
	
	//search from book
	assocBookSearch:function(bookId, rNum, kNum, wNum){
		if(!bookId) return;
		this.assocType = AssocType.DETAIL;
		
		var resultNum = (rNum != null) ? rNum : this.resultNum;
		var keywordsNum = (kNum != null) ? kNum : SearchManagerConfig.DEFAULT_KEYWORD_NUM;
		var wikipediaNum = (wNum != null) ? wNum : SearchManagerConfig.DEFAULT_WIKIPEDIA_NUM;
		
		var option = {
			book_id:bookId,
			start_num:0,
			keywords_num:keywordsNum,
			wikipedia_num:wikipediaNum
		};
		this.conditionObj = option;
		this.searchPath = FixedValues.API_ASSOC_BOOK_PATH;
		
		this._assocSearch(false, resultNum);
	},
	
	//search from detail page
	assocDetailSearch:function(text){
		if(!text || text == ""){
			SearchManager.errorMessage = "検索テキストが含まれていません。";
			Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
			return;
		}
		this.assocType = AssocType.DETAIL;
		
		var option = {
			text:text,
			start_num:0,
			keywords_num:SearchManagerConfig.DEFAULT_KEYWORD_NUM,
			wikipedia_num:SearchManagerConfig.DEFAULT_WIKIPEDIA_NUM
		};
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_ASSOC_TEXT_PATH;
		
		this._assocSearch(false);
	},
	
	//search using keyword
	assocAddKeySearch:function(keyword, incFlg){
		var keyStr;
		keyword = "\"" + keyword + "\"";
		if(this.conditionObj.keywords){
			var keywords = this.conditionObj.keywords.split(",");
			for(var i = 0; i < keywords.length; i++){
				var data = keywords[i].split(":");
				var type = data[0];
				var key = data[1];
				
				if(key == keyword){
					keywords.splice(i,1);
					this.conditionObj.keywords = keywords.join(",");
					break;
				}
			}
		}
		
		if(incFlg) keyStr = "i:" + keyword;
		else keyStr = "e:" + keyword;
		
		if(!this.conditionObj.keywords) this.conditionObj.keywords = "";
		else this.conditionObj.keywords += ",";
		
		this.conditionObj.keywords += keyStr;
		var condition = copyObject(this.conditionObj);
		HistoryManager.setURL(SearchManager, SearchManager._doAssocKeySearch, condition, SearchManager.assocType, SearchManager.searchPath);
	},
	
	//remove search keyword
	assocRemoveKeySearch:function(keyword){
		keyword = "\"" + keyword + "\"";
		if(this.conditionObj.keywords){
			var keywords = this.conditionObj.keywords.split(",");
			for(var i = 0; i < keywords.length; i++){
				var data = keywords[i].split(":");
				var type = data[0];
				var key = data[1];
				
				if(key == keyword){
					keywords.splice(i,1);
					this.conditionObj.keywords = keywords.join(",");
					break;
				}
			}
		}
		
		//this._assocSearch(false);
		var condition = copyObject(this.conditionObj);
		HistoryManager.setURL(SearchManager, SearchManager._doAssocKeySearch, condition, SearchManager.assocType, SearchManager.searchPath);
	},
	
	_doAssocKeySearch:function(condition, type, path){
		this.assocType = type;
		this.conditionObj = condition;
		this.searchPath = path;
		
		switch(type){
			case AssocType.TEXT:
				this.conditionObj.text = condition.text;
				break;
			case AssocType.SHELF:
				delete this.conditionObj.text;
				break;
			case AssocType.WIKIPEDIA:
				delete this.conditionObj.text;
				break;
			case AssocType.DETAIL:
				if(condition.text) this.conditionObj.text = condition.text;
				break;
		}
		
		this._assocSearch(false);
	},
	
	//do associative search more
	assocMoreSearch:function(moreNum){
		this.conditionObj.start_num = this.resultObj.results.length;
		this.conditionObj.keywords_num = 0;
		this.conditionObj.wikipedia_num = 0;
		
		this._assocSearch(true, moreNum);
	},
	
	//do associative search
	_assocSearch:function(addFlg, resultNum){
		//GlobalValues.searchMode = SearchMode.ASSOC;
		GlobalValues.resultType = ResultType.ASSOC_BOOK;
		if(!addFlg) Observer.dispatchEvent(GlobalEvent.ASSOC_SEARCH, SearchManager);
		
		this.conditionObj.result_num = (resultNum) ? resultNum : this.resultNum;
		if(this.conditionObj.result_num > this.MAX_ASSOC_RESULT_NUM) this.conditionObj.result_num = this.MAX_ASSOC_RESULT_NUM;
		//this.conditionObj._type = "json";
		if(this.xhr) this.xhr.abort();
		this.xhr = $.ajax({
			type	: SearchManager.METHOD,
			url		: this.searchPath,
			data	: this.conditionObj,
			dataType: 'json',
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				SearchManager.xhr = null;
				trace(request);
				trace(status);
				if(status == "timeout") SearchManager.errorMessage = "サーバーが混み合っています。時間を空けて再度お試しください。";
				Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
			},
			success	: function(json){
				SearchManager.xhr = null;
				if(json.status.code != 0 || json.result_total == 0){
					var content = ""
					
					if(json.content) {
						var tempString = json.content.replace(/\"/g, "");
						var tempArray = tempString.split(',');
						if(GlobalValues.resultType == ResultType.MATCH_BOOK) {
							tempArray.splice(tempArray.length-3, 3);
							//trace("spliced
						}
					
						var content = tempArray.join(" ");
						content = content.replace(/\s+/g, " ");
						content = content.replace(/\s$/, "");
					
						content = "“"+ content +"”に該当する情報はありませんでした。<br />検索条件を変更して、再度検索してください。";
					}
					else{
						content = json.status.message;
					}
					
					SearchManager.errorMessage = content;
					//SearchManager._setErrorMessage(json.status.code, content);
					Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
					return;
				}
				
				if(!addFlg){
					SearchManager.resultObj = json;
					Observer.dispatchEvent(GlobalEvent.ASSOC_SEARCHED, SearchManager);
				}else{
					SearchManager.moreResultObj = json.results;
					SearchManager.resultObj.results = SearchManager.resultObj.results.concat(json.results);
					Observer.dispatchEvent(GlobalEvent.ASSOC_MORE_SEARCHED, SearchManager);
				}
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});

	},
	
	
	matchBookKeywordSearch:function(keyword, details, order){
		GlobalValues.resultType = ResultType.MATCH_BOOK;
		this.keyword = keyword;
		var detailArr = copyArray(details);
		this.matchDetailArr = (detailArr) ? detailArr : new Array(SearchManagerConfig.MATCH_DETAIL_BOOK_NUM);
		this.order = (order) ? order : 0;
		var option = {
			keyword:keyword,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_BOOK_NUM),
			order:(order) ? order : 0,
			drilldown_num:SearchManagerConfig.DEFAULT_BOOK_DRILL_NUM
		}
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_BOOK_KEYWORD_PATH;
		
		this._matchSearch(false);
	},
	
	
	matchBookCreatorSearch:function(creator_id){
		GlobalValues.resultType = ResultType.MATCH_BOOK;
		this.matchDetailArr = new Array(SearchManagerConfig.MATCH_DETAIL_BOOK_NUM);
		var option = {
			creator_id:creator_id,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_BOOK_NUM),
			order:0,
			drilldown_num:SearchManagerConfig.DEFAULT_BOOK_DRILL_NUM
		}
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_BOOK_PERSON_PATH;
		
		this._matchSearch(false);
	},
	
	
	matchBookWorksSearch:function(work_id){
		GlobalValues.resultType = ResultType.MATCH_BOOK;
		this.matchDetailArr = new Array(SearchManagerConfig.MATCH_DETAIL_BOOK_NUM);
		var option = {
			work_id:work_id,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_BOOK_NUM),
			order:0,
			drilldown_num:SearchManagerConfig.DEFAULT_BOOK_DRILL_NUM
		}
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_BOOK_WORKS_PATH;
		
		this._matchSearch(false);
	},
	
	
	matchWorksKeywordSearch:function(keyword, details, order){
		GlobalValues.resultType = ResultType.MATCH_WORKS;
		this.keyword = keyword;
		var detailArr = copyArray(details);
		this.matchDetailArr = (detailArr) ? detailArr : new Array(SearchManagerConfig.MATCH_DETAIL_WORK_NUM);
		this.order = (order) ? order : 0;
		var option = {
			keyword:keyword,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_WORK_NUM),
			order:(order) ? order : 0,
			drilldown_num:SearchManagerConfig.DEFAULT_WORK_DRILL_NUM
		}
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_WORKS_KEYWORD_PATH;
		
		this._matchSearch(false);
	},
	
	
	matchWorksCreatorSearch:function(creator_id){
		GlobalValues.resultType = ResultType.MATCH_WORKS;
		this.matchDetailArr = new Array(SearchManagerConfig.MATCH_DETAIL_WORK_NUM);
		var option = {
			creator_id:creator_id,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_WORK_NUM),
			order:0,
			drilldown_num:SearchManagerConfig.DEFAULT_WORK_DRILL_NUM
		}
		
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_WORKS_PERSON_PATH;
		
		this._matchSearch(false);
	},
	
	
	matchCreatorKeywordSearch:function(keyword, details, order){
		GlobalValues.resultType = ResultType.MATCH_PERSON;
		this.keyword = keyword;
		var detailArr = copyArray(details);
		this.matchDetailArr = (detailArr) ? detailArr : new Array(SearchManagerConfig.MATCH_DETAIL_CREATOR_NUM);
		this.order = (order) ? order : 0;
		var option = {
			keyword:keyword,
			start_num:0,
			details:this._getMatchDetailStr(this.matchDetailArr, SearchManagerConfig.MATCH_DETAIL_CREATOR_NUM),
			order:(order) ? order : 0,
			drilldown_num:SearchManagerConfig.DEFAULT_CREATOR_DRILL_NUM
		}
		this.conditionObj = option;
		this.searchPath = FixedValues.API_MATCH_PERSON_KEYWORD_PATH;
		
		this._matchSearch(false);
	},
	
	_getMatchDetailStr:function(detailArr, len){
		var returnStr = "";
		for(var i = 0; i < len; i++){
			var str = "";
			if(detailArr[i]) str = detailArr[i].replace(/"/g, "\"\"");
			returnStr += "\"" + str + "\"";
			if(i != len - 1) returnStr += ",";
		}
		return returnStr;
	},
	
	/*getMatchDetailArr:function(){
		return this.matchDetailArr;
	},*/
	
	matchMoreSearch:function(moreNum){
		this.conditionObj.start_num = this.resultObj.results.length;
		this.conditionObj.drilldown_num = 0;
		
		this._matchSearch(true, moreNum);
	},
	
	matchOrderSearch:function(order){
		switch(GlobalValues.resultType) {
			case (ResultType.MATCH_BOOK) : 
				HistoryManager.setURL(SearchManager, SearchManager.matchBookKeywordSearch, this.keyword, this.matchDetailArr, order);
				break;
			case (ResultType.MATCH_WORKS) :
				HistoryManager.setURL(SearchManager, SearchManager.matchWorksKeywordSearch, this.keyword, this.matchDetailArr, order);
				break;
			case (ResultType.MATCH_PERSON) :
				HistoryManager.setURL(SearchManager, SearchManager.matchCreatorKeywordSearch, this.keyword, this.matchDetailArr, order);
				break;
		}
	},
	
	matchAddDrilldownSearch:function(name, value){
		name = "\"" + name + "\"";
		value = "\"" + value + "\"";
		
		if(!this.conditionObj.drilldown) this.conditionObj.drilldown = "";
		else this.conditionObj.drilldown += ",";
		
		this.conditionObj.drilldown += name +":"+value;
		
		HistoryManager.setURL(SearchManager, SearchManager._doMatchDrilldownSearch, GlobalValues.resultType, this.searchPath, copyObject(SearchManager.conditionObj), copyArray(this.matchDetailArr));
	},
	
	
	matchRemoveDrilldownSearch:function(name, value){
		if(!this.conditionObj || !this.conditionObj.drilldown) return;
		
		var drillArr = this.getMatchDrilldownArr();
		var len = drillArr.length;
		for(var i = 0; i < len; i++){
			if(drillArr[i][0] == name && drillArr[i][1] == value){
				drillArr.splice(i,1);
				break;
			}
		}
		this.conditionObj.drilldown = "";
		len = drillArr.length;
		for(i = 0; i < len; i++){
			this.conditionObj.drilldown += "\""+ drillArr[i][0] + "\":\"" + drillArr[i][1] + "\"";
			if(i != len - 1) this.conditionObj.drilldown += ",";
		}
		
		HistoryManager.setURL(SearchManager, SearchManager._doMatchDrilldownSearch, GlobalValues.resultType, this.searchPath, copyObject(SearchManager.conditionObj), copyArray(this.matchDetailArr));
	},
	
	
	_doMatchDrilldownSearch:function(resultType, path, conditionObj, details){
		GlobalValues.resultType = resultType;
		this.searchPath = path;
		this.conditionObj = copyObject(conditionObj);
		this.matchDetailArr = details;
		
		this._matchSearch(false);
	},
	
	
	//get the array of matching drilldown
	getMatchDrilldownArr:function(){
		if(!this.conditionObj || !this.conditionObj.drilldown) return null;
		
		var returnArr = new Array();
		var drillArr = this.conditionObj.drilldown.match(/"([^"]*)":"([^"]*)",*/g);
		var len = drillArr.length;
		for(var i = 0; i < len; i++){
			var drill = drillArr[i].match(/"([^"]*)":"([^"]*)",*/);
			returnArr.push([drill[1], drill[2]]);
		}
		
		return returnArr;
	},
	
	//do matching search
	_matchSearch:function(addFlg, resultNum){
		this.assocType = null;
		if(!addFlg) Observer.dispatchEvent(GlobalEvent.MATCH_SEARCH, SearchManager);
		
		this.conditionObj.result_num = (resultNum) ? resultNum : this.resultNum;
		//this.conditionObj._type = "json";
		if(this.xhr) this.xhr.abort();
		this.xhr = $.ajax({
			type	: SearchManager.METHOD,
			url		: this.searchPath,
			data	: this.conditionObj,
			dataType: 'json',
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				SearchManager.xhr = null;
				trace(request);
				trace(status);
				if(status == "timeout") SearchManager.errorMessage = "サーバーが混み合っています。時間を空けて再度お試しください。";
				Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
			},
			success	: function(json){
				SearchManager.xhr = null;
				if(json.status.code != 0 || json.result_total == 0){
					//throw new Error(json.status.message);
					
					if(json.content) {
						var tempString = json.content.replace(/\"/g, "");
						var tempArray = tempString.split(',');
						if(GlobalValues.resultType == ResultType.MATCH_BOOK) {
							tempArray.splice(tempArray.length-3, 3);
						}
						
						var content = tempArray.join(" ");
						content = content.replace(/\s+/g, " ");
						content = content.replace(/\s$/, "");

						content = content.replace('<', '&lt;');
						content = content.replace('>', '&gt;');

						content = "“"+ content +"”に該当する情報はありませんでした。<br />検索条件を変更して、再度検索してください。";
					}
					else {
						content = json.status.message;
					}
					
					SearchManager.errorMessage = content;
					//SearchManager._setErrorMessage(json.status.code, content);
					Observer.dispatchEvent(GlobalEvent.ERROR_SEARCH, SearchManager);
					return;
				}
				
				if(!addFlg){
					SearchManager.resultObj = json;
					Observer.dispatchEvent(GlobalEvent.MATCH_SEARCHED, SearchManager);
				}else{
					SearchManager.moreResultObj = json.results;
					SearchManager.resultObj.results = SearchManager.resultObj.results.concat(json.results);
					Observer.dispatchEvent(GlobalEvent.MATCH_MORE_SEARCHED, SearchManager);
				}
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});
	},
	
	checkMatchDrilldown:function(name, value){
		if(!this.conditionObj || !this.conditionObj.drilldown) return false;
		
		/*name = "\"" + name + "\"";
		value = "\"" + value + "\"";
		var len = this.drilldowns.length;
		for(var i = 0; i < len; i++){
			var tname = this.drilldowns[i].name;
			var tvalue = this.drilldowns[i].value;
			
			if(tname == name && tvalue == value){
				return true;
			}
		}
		return false;*/
		
		var drillArr = this.getMatchDrilldownArr();
		var len = drillArr.length;
		for(var i = 0; i < len; i++){
			if(drillArr[i][0] == name && drillArr[i][1] == value){
				return true;
			}
		}
		
		return false;
	},
	
	setResultNum: function(value){
		if (value == 0) {
			this.resultNum = SearchManagerConfig.DEFAULT_RESULT_NUM;
			return;
		}
		this.resultNum = value;
	}
}


//function which manages shelves
var ShelfManager = {
	shelfData:null,
	
	loadAllShelfData:function(){
		var savedId = CookieManager.getShelfSavedId();
		var self = this;
		var url = (savedId) ? FixedValues.API_SHELF_DATA : FixedValues.DATA_SHELF_MONTHLY;
		var dataType = (savedId) ? "json" : "xml";

        if (savedId) {
            //savedId = savedId.replace(/\+/g, '%2B').replace(/=/g, '%3D').replace(/\//g, '%2F');
		    var params = CookieManager.isMember() ? 
                    {openid:savedId} :
                    {saved_id: savedId};
        }

		$.ajax({
			type	: SearchManager.METHOD,
			url		: url,
			data	: params, 
			dataType: dataType,
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				trace(arguments);
				//CookieManager.deleteShelSavedId();
				Observer.dispatchEvent(GlobalEvent.SHELF_LOAD_ERROR, ShelfManager);
			},
			success	: function(data){
				if (savedId) 
					self._loadedSavedShelf(data);
				else 
					self._loadedMonthlyShelf(data);
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});
	},
	
	_loadedSavedShelf:function(json){
		if(json.status && Number(json.status.code) != 0){
			CookieManager.deleteShelSavedId();
			Observer.dispatchEvent(GlobalEvent.SHELF_LOAD_ERROR, ShelfManager);
			return;
		}
		ShelfManager.shelfData = json;
		Observer.dispatchEvent(GlobalEvent.SHELF_LOADED, ShelfManager);
		return;
	},
	
	_loadedMonthlyShelf:function(xml){
		trace(xml);
		ShelfManager.shelfData = {};
		ShelfManager.shelfData.shelves = new Array();
		
		var shelvesXML = xml.getElementsByTagName("shelf");
		trace(shelvesXML);
		for(var i = 0; i < shelvesXML.length; i++){
			var shelfXML = shelvesXML[i];
			var shelf = {};
			//shelf.id = shelfXML.getAttribute('id');//"SL" + ("0000"+String(i)).substr(-4);
			shelf.name = shelfXML.getAttribute("name");
			shelf.color = shelfXML.getAttribute("color");
			shelf.elements = new Array();
			
			var elementsXML = shelfXML.getElementsByTagName("element");
			for(var j = 0; j < elementsXML.length; j++){
				var elementXML = elementsXML[j];
				var element = {};
				var elementId = elementXML.getAttribute("id");
				element.id = (elementId && elementId != "") ? elementId : "EL" + ("0000" + String(j)).substr(-4);
				element.title = elementXML.getAttribute("title");
				element.type = elementXML.getAttribute("type");
				shelf.elements.push(element);
			}
			
			ShelfManager.shelfData.shelves.push(shelf);
		}
		
		ShelfManager.setMonthlyShelf();
	},
	
	//save monthly shelfdata to server
	setMonthlyShelf:function(){
		var shelfCount = 0;
		var elemCount = 0;
		var shelfData;
		
		var createShelf = function(){
			shelfData = ShelfManager.shelfData.shelves[shelfCount];
			Observer.addEventListener(GlobalEvent.SHELF_CREATED, ShelfManager, createdShelf, self);
			ShelfManager.createShelf();
		};
		
		var createdShelf = function(){
			shelfCount++;
			
			Observer.removeEventListener(GlobalEvent.SHELF_CREATED, ShelfManager, createdShelf, self);
			Observer.addEventListener(GlobalEvent.SHELF_RENAMED, ShelfManager, changedName, ShelfManager);
			Observer.addEventListener(GlobalEvent.SHELF_RECOLORED, ShelfManager, changedColor, ShelfManager);
			ShelfManager.renameShelf(shelfData.id, shelfData.name);
		};
		
		var changedName = function(){
			Observer.removeEventListener(GlobalEvent.SHELF_RENAMED, ShelfManager, changedName, ShelfManager);
			ShelfManager.recolorShelf(shelfData.id, shelfData.color);
		};
		
		var changedColor = function(){
			Observer.removeEventListener(GlobalEvent.SHELF_RECOLORED, ShelfManager, changedColor, ShelfManager);
			if(!shelfData.elements || shelfData.elements.length == 0){
				finishSet();
			} else {
				Observer.addEventListener(GlobalEvent.SHELF_ELEMENT_ADDED, ShelfManager, addedElement, ShelfManager);
				elemCount = 0;
				addElement();
			}
		}
		
		var addElement = function(){
			var info = shelfData.elements[elemCount];
			ShelfManager.addShelfElement(shelfData.id, info.id, info.type, info.title);
			
		};
		
		var addedElement = function(){
			elemCount++;
			if(elemCount == shelfData.elements.length){
				Observer.removeEventListener(GlobalEvent.SHELF_ELEMENT_ADDED, ShelfManager, addedElement, ShelfManager);
				if(shelfCount == ShelfManager.shelfData.shelves.length || shelfCount >= 6){
					//Observer.removeEventListener(GlobalEvent.SHELF_CREATED, ShelfManager, createdShelf, ShelfManager);	
					finishSet();
					return;
				}

				createShelf();
				return;
			}
			
			addElement();
		};
		
		var finishSet = function(){
			Observer.dispatchEvent(GlobalEvent.SHELF_LOADED, ShelfManager);
		};
		
		var errorSet = function(){
			Observer.removeEventListener(GlobalEvent.SHELF_EDIT_ERROR, ShelfManager, createdShelf, self);
			Observer.removeEventListener(GlobalEvent.SHELF_CREATED, ShelfManager, createdShelf, self);
			Observer.removeEventListener(GlobalEvent.SHELF_RENAMED, ShelfManager, changedName, ShelfManager);
			Observer.removeEventListener(GlobalEvent.SHELF_ELEMENT_ADDED, ShelfManager, addedElement, ShelfManager);
			
			Observer.dispatchEvent(GlobalEvent.SHELF_LOAD_ERROR, ShelfManager);
			CookieManager.deleteShelSavedId();
		};
		
		Observer.addEventListener(GlobalEvent.SHELF_EDIT_ERROR, ShelfManager, createdShelf, self);
		createShelf();
	},
	
	//change the name of shelf in server. it might be called at only first time.
	createShelf:function(id){
		var params = {
			//shelf_id	: id,
			code		: 101
		};
		var saved_id = CookieManager.getShelfSavedId();
		if (saved_id) {
			params.saved_id = saved_id;
		}
		this._editShelf(GlobalEvent.SHELF_CREATED, params);
	},
	
	//change the name of shelf in server. it might be called at only first time.
	renameShelf:function(shelfId, name){
		var params = {
			saved_id	: CookieManager.getShelfSavedId(),
			shelf_id	: shelfId,
			code		: 202,
			option		: name
		};
		
		this._editShelf(GlobalEvent.SHELF_RENAMED, params);
	},
	
	recolorShelf:function(shelfId, color){
		var params = {
			saved_id	: CookieManager.getShelfSavedId(),
			shelf_id	: shelfId,
			code		: 203,
			option		: color
		};
		
		this._editShelf(GlobalEvent.SHELF_RECOLORED, params);
	},
	
	//add shelf elements to server. it might be called at only first time.
	addShelfElement:function(shelfId, elemId, type, title){
		var savedId = CookieManager.getShelfSavedId();
		var params = {
			saved_id	: savedId,
			shelf_id	: shelfId,
			code		: 301,
			option		: elemId + "," + type + "," + title + "," + 0
		};
		
		this._editShelf(GlobalEvent.SHELF_ELEMENT_ADDED, params);
	},
	
	_editShelf:function(event, params){
		if (CookieManager.isMember() && params.saved_id) {
			var id = params.saved_id;
			delete params.saved_id;
			params.openid = id;
		}
		
		$.ajax({
			type	: SearchManager.METHOD,
			url		: FixedValues.API_SHELF_EDIT,
			data	: params,
			dataType: 'json',
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				trace(request);
				trace(status);
				Observer.dispatchEvent(GlobalEvent.SHELF_EDIT_ERROR, ShelfManager);
			},
			success	: function(json){
				if (event == GlobalEvent.SHELF_CREATED) {
                    CookieManager.setShelfSavedId(json.saved_id);

                    var i = 0;
                    while (ShelfManager.shelfData.shelves[i].id) {
                        i++;
                    }
                    ShelfManager.shelfData.shelves[i].id = json.item.id;
                }
				Observer.dispatchEvent(event, ShelfManager);
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});
	}
}



var CookieConfig = {
	SHELF_ID:"shid",
    SHELF_ID_MEMBER:"openid",
	SKIN_ID:"skid",
	TAB:"tab",
	TAB_POS:"tpos",
	MAX_CHARACTOR:2000
}

var CookieManager = {
    isMember: function () {
        return !!$.cookie(CookieConfig.SHELF_ID_MEMBER);
    },

	getShelfSavedId:function(){
        var id = $.cookie(CookieConfig.SHELF_ID_MEMBER);
        if (id) {
            return id.replace(/\+/g, '%2B').replace(/=/g, '%3D').replace(/\//g, '%2F');
        }

	    return $.cookie(CookieConfig.SHELF_ID);
	},
	
	setShelfSavedId:function(savedId){
		$.cookie(CookieConfig.SHELF_ID, savedId, {expires: 10000, path:'/'});
	},
	
	deleteShelSavedId:function(){
		$.cookie(CookieConfig.SHELF_ID, '', { expires: -1 });
	},
	
	getSkinId:function(){
		return $.cookie(CookieConfig.SKIN_ID);
	},
	
	setSkinId:function(skinId){
		$.cookie(CookieConfig.SKIN_ID, skinId, {expires: 10000, path:'/'});
	},
	
	getTab:function(){
		return $.cookie(CookieConfig.TAB);
	},
	
	setTab:function(str){
		$.cookie(CookieConfig.TAB, str, {expires: 10000, path:'/'});
	},
	
	deleteTab:function(){
		$.cookie(CookieConfig.TAB, '', {expires: -1 });
	},
	
	getTabPos:function(){
		return Number($.cookie(CookieConfig.TAB_POS));
	},
	
	setTabPos:function(pos){
		$.cookie(CookieConfig.TAB_POS, pos, {expires:10000, path:'/'});
	}

}




var WhatIsTodayManager = {
	todayData:null,
	getToday:function(){
		var date = new Date();
		var monthStr = this.setKeta(date.getMonth() + 1, 2);
		var dayStr = this.setKeta(date.getDate(), 2);
		var dateStr = monthStr + "/"+ dayStr;
		
		$.ajax({
			type	: SearchManager.METHOD,
			url		: FixedValues.API_WHAT_IS_TODAY_PATH,
			data	: "date="+dateStr,
			dataType: 'json',
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				trace(request);
				trace(status);
			},
			success	: function(json){
				if(json.status.code != 0){
					//throw new Error(json.status.message);
					return;
				}
				
				WhatIsTodayManager.todayData = json.result;
				Observer.dispatchEvent(GlobalEvent.TODAY_LOADED, WhatIsTodayManager);
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});
	},
	
	getTodayLink:function(){
		var date = new Date();
		var month = date.getMonth() + 1;
		var date = date.getDate();
		return "http://ja.wikipedia.org/wiki/"+month+"月"+date+"日";
	},
	
	setKeta:function(num, keta){
		var numStr = new String(num);
		var count = keta - numStr.length;
		if(count <= 0) return numStr;
		while(count-- > 0) numStr = "0" + numStr;
		
		return numStr;
	}
}



function setErrorMessage(status){
	switch(status){
		case 1:
			
			break;
		case 5:
			break;
		case 6:
			break;
		case 9:
			break;
	}
}




var InfoManager = {
	infoData:new Array(),
	loadInfo:function(){
		$.ajax({
			type	: SearchManager.METHOD,
			url		: FixedValues.DATA_INFO_PATH,
			dataType: 'xml',
			timeout	: SearchManager.TIMEOUT,
			error	: function(request,status){
				trace(request);
				trace(status);
				Observer.dispatchEvent(GlobalEvent.INFO_ERROR, InfoManager);
			},
			success	: function(xml){
				var infoArr = xml.getElementsByTagName("info");
				var len = infoArr.length;
				for(var i = 0; i < len;  i++){
					var date = infoArr[i].getElementsByTagName("date")[0].firstChild.nodeValue;
					var content = infoArr[i].getElementsByTagName("content")[0].firstChild.nodeValue;
					
					InfoManager.infoData.push({date:date, content:content});
				}
				
				Observer.dispatchEvent(GlobalEvent.INFO_LOADED, InfoManager);
			},
			beforeSend : function( xhr ){
				xhr.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
			}
		});
	}
}
