var PROTO = location.protocol;
var BASE_URL = PROTO + "//www.knowd.co.jp/";
var URL_PREFIX = "";

var VERSION = "0.5.22";
var REVISION = "2011.11.24";
var TOP = "Knowledge Design Corporation 2011.12";
var SLOGAN = "エンジニア、開発者向けの技術トレーニング、セミナーを開発、実施しています。";
var COMPANY_NAME = '有限会社ナレッジデザイン - Knowledge Design Corporation';
var COMPANY_ADDRESS = '住所: 〒1830023　東京都府中市宮町1-40 府中サウスビル 7階';
var COMPANY_CONTACTS ='電話番号: <a href="tel:042.318.7127">042-318-7124</a> ファックス番号: <a href="tel:042.318.7136">042-318-7136</a>';

var RESOURCE_URL = PROTO + "//www.knowd.co.jp/cgi-bin/courses.cgi";
var EVENT_URL = PROTO + "//www.knowd.co.jp/cgi-bin/events.cgi";

var NEWS_URL = PROTO + '//www.knowd.co.jp/drupal7';
var BLOG_URL = PROTO + "//www.knowd.co.jp/drupal7/?q=aggregator/categories/1";	
var TECH_URL = PROTO + "//www.knowd.co.jp/dokuwiki";

var COUNTER_URL = PROTO + "//www.knowd.co.jp/cgi-bin/counter.cgi";

// Authentication
/* for testing
var AUTHN_URL = PROTO + "//www.knowd.co.jp/cgi-bin/authn.cgi";
var PROF_URL = PROTO + "//www.knowd.co.jp/cgi-bin/profile.cgi";
var REGIST_URL = PROTO + "//www.knowd.co.jp/cgi-bin/signup.cgi";
var PASSWORD_REMINDER_URL = PROTO + "//www.knowd.co.jp/cgi-bin/password-reminder.cgi";
*/
/*
var AUTHN_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/authn.cgi";
var PROF_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/profile.cgi";
var REGIST_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/signup.cgi";
var PASSWORD_REMINDER_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/password-reminder.cgi";
var REGIST_CONFIRM_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/confirm.cgi";
var REMOVE_URL = PROTO + "//test02.knowd.co.jp/cgi-bin/signoff.cgi";
*/

var AUTHN_URL =             BASE_URL + "cgi-bin/authn.cgi";
var PROF_URL =              BASE_URL + "cgi-bin/profile.cgi";
var REGIST_URL =            BASE_URL + "cgi-bin/signup.cgi";
var PASSWORD_REMINDER_URL = BASE_URL + "cgi-bin/password-reminder.cgi";
var REGIST_CONFIRM_URL =    BASE_URL + "cgi-bin/confirm.cgi";
var REMOVE_URL =            BASE_URL + "cgi-bin/signoff.cgi";

var TAB_POS = {
	"top" :     0,
	"news" :    1,
	"company" : 2,
	"training": 3,
	"tech" :    4,
	"staff" :   5,
	"contact" : 6,
	"account":  5
};

var AUTH_CACHE;


var SWITCH_IMAGE_TIMER;
var SWITCH_IMAGE_INTERVAL = 20000;
var OPEN_STRING = "open";
var CLOSE_STRING = "close";

var CACHED_ALL_COURSE = pullAllCourse();
var CACHED_ALL_EVENT = pullAllEvent();
// 1 hour.
var CACHE_LIMIT_SEC = 60 * 60 * 1000; 
// 1 min.
//var CACHE_LIMIT_SEC = 60 * 1000; 

//var CACHE_LIMIT_SEC = 15000; // 15 sec for Test.

/*
 * 2011.11.21 - 0.5.21
 * feed link add.
 *
 * 2011.11.21 - 0.5.20
 * Google Map (comapny_access.html)
 *
 * 2011.11.19 - 0.5.13
 * www.knowd.co.jp
 *
 * 2011.11.15 - 0.5.12
 * 
 * 2011.11.11 - 0.5.11
 * favicon, jQuery 1.7.
 *
 * 2011.10.10 - 0.5.01
 * change cache from sessionStorage to localStorage.
 * login panel add.
 *
 * 2011.10.5 - 0.4.17
 * image rotation interval could be configureble.
 *
 * 2011.10.5 - 0.4.15
 * Top Image next and pointed URL.
 *
 * 2011.10.3 - 0.4.11
 * add feed cache.
 *
 * 2011.10.2 - 0.4.10
 * Integration to Druapl by Feed.
 * 
 * 2011.10.2 - 0.4.05
 * add News Tab, link to Drupal.
 *
 * 2011.10.1 - 0.4.04
 * top tab generate by JS. 
 *
 * 2011.9.30 - 0.4.02
 * add jQueryTools, and Web Technology category, footer and course sub menu generate by JS.
 *
 * 2011.9.29 - 0.3.14
 * add Quiz. 
 *
 2* 2011.9.27 - 0.3.13
 * Ajax Access counter. 
 *
 * 2011.9.25 - 0.3.12
 * add course list, SVG drop.
 *
 * 2011.9.24 - 0.3.9
 * text image SVG.
 *
 * 2011.9.23 - 0.3.8
 * click related course and open detail.
 *
 * 2011.9.22 - 0.3.7
 * Web Storage (DOM Storage).
 *
 */


$( function() {
	jQuery.support.cors = true;
	//localStorage.clear();
	makeAuthCache();
	makeHeader();
	makeLogin();
	getVersion();
	pullAllCourse();
	pullAllEvent();
	goTop();
	counterIncrement();
	makeFooter();
	setSessionClearButton();
	googleAnalytics();
	makeBanner();
	appendStatCounter();
});

function makeBanner() {
	var banner = $('#banner').html( "<span style='color:red;'>Campaign!</span> <a href='http://www.knowd.co.jp/news'>Android / LPI Level 3 キャンペーン中!!</a>");
	$("body").prepend(banner);
};

function googleAnalytics() {
	var _gaq = _gaq || [];
	_gaq.push(['_setAccount', 'UA-2969801-1']);
	_gaq.push(['_trackPageview']);

	(function() {
    	var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    	ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    	var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
	})();
}

function makeAuthCache() {
	if (!localStorage.auth_result) {
		jQuery.ajax({
			type: "POST",
			url: AUTHN_URL,
			data: {"session": "1"},
			async: false,
			dataType: "json",
			success: function(result) {
				localStorage.auth_result = JSON.stringify(result);
			},
			error: function(e, status) { 
				/*alert(e.statusText);*/
			 },
		});
	}
	//AUTH_CACHE = JSON.parse(localStorage.auth_result);
	AUTH_CACHE = jQuery.parseJSON(localStorage.auth_result);
}

function makeLogin() {
	var loginPanel = new LoginPanel();
	var panel = loginPanel.getPanel();

	$('#login_panel').remove();
	$('#masthead').append(panel);
	/*
	if( localStorage.auth_result ) {
		AUTH_CACHE = JSON.parse(localStorage.auth_result);
	}
	*/
	if (!AUTH_CACHE) {
		jQuery.ajax( {
			type: "POST",
			url: AUTHN_URL, 
			async: true,
			data: {"session":"1"},
			dataType: "json",
			xhrFields: { withCredentials: true },
			success: function(result) {
				loginPanel.setResult(result);
				localStorage.auth_result = JSON.stringify(result);
			}
		});
	} else {
		loginPanel.setResult(AUTH_CACHE);
	}
}

function LoginPanel() {
	this.panel = $("<div>");
	this.id = "login_panel";
	this.clazz = "login_panel";

	this.panel.attr("id", this.id);
	this.panel.addClass(this.clazz);
	this.panel.html("Login Panel loading...");
}

LoginPanel.prototype = {
	getPanel: function() {
		return this.panel;
	},

	setResult: function(result) {
		var panelContent = $('<div>').html("読み込み中...");
		this.panel.append(panelContent);
		if (result.id > 0) {
			panelContent = this.loggedIn(result);
		} else {
			panelContent = this.loggedOut(result);
		}
		this.panel.empty();
		this.panel.append(panelContent);
	},

	loggedIn: function(result) {
		if (!result.user) {
			return this.loggedOut(result);
		}
		var message = $('<div>');
		var lamp = $("<img>").attr("src",BASE_URL + "img/login.png").addClass("login_lamp").appendTo(message);
		
		message.append( $("<div>").addClass('logged_in').text('サインイン中'));
		var profLink = $('<a>').attr("href", "signin.html").append($('<div>').html( result.user.lname + " " + result.user.fname + " 樣"));
		message.append(profLink);
		var logoutButton = $('<input>').attr({"type":"button"}).val("ログアウト").appendTo(message);
		logoutButton.click( function(e) {
			jQuery.ajax({
				type: "POST",
				async: false,
				url: AUTHN_URL,
				xhrFields: { withCredentials: true },
				data: {
					"c": "logout",
					"session": "1"
				},
				dataType: "json",
				success: function(result, status, xhr) { processResult(result, status, xhr); },
				error: function(xhr, options, thrownError) { 
					localStorage.removeItem("auth_result"); 
					//alert("ERROR: " + xhr.statusText); 
					location.reload();
				},
				complete: function() { makeLogin(); },
			})
		});
		
		return message;
	},

	logWait: function(result) {
		var message = $('<div>');
		var lamp = $("<img>").attr("src",BASE_URL + "img/logwait.png").addClass("login_lamp").appendTo(message);
		message.append( $("<div>").text('メールによる確認を待機中.'));
	},

	loggedOut: function(result) {
		var message = $('<div>');
		var lamp = $("<img>").attr("src",BASE_URL + "img/logout.png").addClass("login_lamp").appendTo(message);
		var default_mail = "your mail address";
		$('<span>').html("E-Mail: ").appendTo(message);
		var inputEmail = $('<input>').attr({"id":"email", "size":"18"}).appendTo(message);
		if(localStorage.sentEmail) {
			inputEmail.val(localStorage.sentEmail);
		}
		if(inputEmail.val() == "") {
			inputEmail.val(default_mail).css({"color":"gray"});
		}
		inputEmail.focus( function(e) { 
			if($(this).val() == default_mail) {
				$(this).val("").css("color","gray");
			} else {
				$(this).css("color","black");
			}
		});
		inputEmail.focusout( function(e){ if($(this).val() == "") { $(this).val(default_mail).css("color","grey"); } } );

		$('<br>').appendTo(message);
		$('<span>').html("Password: ").appendTo(message);
		var inputPassword = $('<input>').attr({"type":"password", "id":"password", "size":"18"}).appendTo(message);
		$('<br>').appendTo(message);

		var regLink = $('<a>').attr("href", "signup.html").append( $('<span style="color: orange; margin-right:1em;">').html("サインアップ") );
		message.append(regLink);
		var loginButton = $('<input>').attr({"type":"button"}).val("サインイン").appendTo(message);

		loginButton.click( function(e) {
			if ($("#email").val() != "" && $("#email").val() != default_mail){
				localStorage.sentEmail = $("#email").val();
			}
			jQuery.ajax({
				type: "POST",
				url: AUTHN_URL,
				async: false,
					xhrFields: { withCredentials: true },
				dataType: "json",
				data: {
					"c":"login",
					"session": "1",
					"u":$('#email').val(),
					"p":$('#password').val() },
				success: function(result, status, xhr) { processResult(result, status, xhr); },
				error: function(xhr, options, thrownError) { 
					localStorage.removeItem("auth_result"); 
					alert("サインインに失敗しました。\nユーザー名、またはパスワードを確認して下さい。"); 
					location.reload();
				},
				complete: function() { makeLogin(); },
			})
		});

		inputEmail.keypress( function(e){ if(isEnter(e)){ loginButton.click();}; if($(this).val() == default_mail){ $(this).css("color","gray");} else { $(this).css("color","black");} });
		inputPassword.keypress( function(e){ if(isEnter(e)){ loginButton.click();} });

		
		return message;
	},

};

function isEnter(e) {
	return (e.which == 13) ? true : false;
}
	

function processResult(result, textStatus, xhr) {
	localStorage.auth_result = JSON.stringify(result);
	location.reload();
}

function getRSSFeed(target, url, n, detail_url, title) {
	var titleH = $('<h4>').text(title).css('border-bottom', "1px solid gray");
	var feedIcon = $('<a>').attr("href",url).append($('<img>').attr({"src":"/img/feed.png"}).css("margin-left", "0.5em"));
	titleH.append(feedIcon);
	target.append(titleH);
	var cache = pullFeed(url, target, n, detail_url);
	//makeFeed( target, $(cache), detail_url, n);
}

function makeFeed( target, itemsXML, detail_url, n ) {
	if (!n) n = 10;
	var xmlDoc = $(jQuery.parseXML(itemsXML));
	var items = $(xmlDoc).find("item");
	for ( var i = 0; i < n && i < items.length; i++ ) {
		var item = $(items[i]);
		var title = item.find("title").text();
		var link = item.find("link").text();
		var pd = new Date(Date.parse(item.find("pubDate").text()));
		//var pubDate = pd.getFullYear() + "/" + nf(pd.getMonth()+1) + "/" + nf(pd.getDate()) + ": ";
		var pubDate = nf(pd.getMonth()+1) + "/" + nf(pd.getDate()) + "/" + (pd.getFullYear().toString()).substr(2,2) + ":";
		var panel = $('<div>').addClass('feed_panel');
		var pubDateP = $('<span>').css({"color": "gray", "font-size": "x-small", "font-family":"monospace"}).html(pubDate).appendTo(panel);
		var linkP = $('<a>').attr("href", link).appendTo(panel);
		var titleP = $('<span>').css('font-size', 'x-small').html(title).appendTo(linkP);

		target.append(panel);
	}

	$('<div>').append($('<a>').attr("href", detail_url).text(".. より詳しく ..") ).css({"font-size":"x-small", "margin-top": "0.5em", "text-align": "left"}).appendTo(target);
}

function nf(n) {
	if ( n < 10 ) {
		return "&nbsp;" + n;
	}
	return n;
}

function setSessionClearButton() {
	var b = $("<input type='button'>").attr("value", "clear localStorage").click( function(e) {
		localStorage.clear();
		alert("localStorage cleared");
		location.reload();
	});
	$("#footer").before(b);
}

function counterIncrement() {
	var user = ( AUTH_CACHE && AUTH_CACHE.user ) ? AUTH_CACHE.user.mail : "";		

	var r = {
		"user" : user,
		"uri" : location.pathname,
		"userAgent" : navigator.userAgent
	};
	jQuery.ajaxSetup({async:true});
	jQuery.post( COUNTER_URL, r, 
		function(data) { 
			/* $("#version").append( $("<span>").text(" count: " + data.count + " / " + data.total_count ) ); */
		},
	 	"json" 
	);
}

function goTop() {
	var goTopArrow = $('<div>').click(function(){ window.scroll(0, 0); }).addClass("gotop").attr( { id: "goTopArrow" } );

	$("body").append(goTopArrow);
	goTopArrow.hide();
	
	$(window).scroll( function() { 
		if ($("html").position().top != 0 ) {
			$("#goTopArrow").show("slow"); 
		} else {
			$("#goTopArrow").hide("slow");
		}
	} );
}

function makeHeader() {
	$("head").append( $("<title>").text(TOP + " : " + VERSION));
	var header = $('#masthead').addClass('container_12 masthead');
	header.append( $('<span id="banner">') );
	//header.append( $('<img id="logo">').attr({src: BASE_URL + "/img/kdc_header_logo.png"}).click(function(){ location = URL_PREFIX + "/" }));
	header.append( $('<img id="logo">').attr({src: "/img/kdc_header_logo.png"}).click(function(){ location = URL_PREFIX + "/" }));
	header.append( $('<div id="top">').text(TOP) );
	header.append( $('<div id="slogan">').text(SLOGAN) );
	
	/*
	$("body").append(
		 $("<div>")
		.attr("id", "center-message")
		.css({	"float": "both",
				"position": "fixed",
				"top":		"40%",
				"left":		"45%",
				"width":	"75px",
				"height":	"75px",
				"background": "url(img/loadinfo.net.gif) no-repeat",
		 		"z-index":	120
		 })
		 .html("<br><br>loading...").hide()
	);
	*/
}

function makeFooter() {	
	var footer = $('#footer').addClass('footer');
	var link = $('<a>').attr('href',BASE_URL);
	var logo = $('<img>').attr("src", BASE_URL + "img/kdclogo1-16s.gif").css({"float":"right", "margin-left": "1em"});
	link.append(logo);
	footer.append(link);
	$('<div>').html(COMPANY_NAME).appendTo(footer);
	$('<div>').html(COMPANY_ADDRESS).appendTo(footer);
	$('<div>').html(COMPANY_CONTACTS).appendTo(footer);	
	$("body:last").append(footer);
}

function makeTab(target, selected) {
	if (!selected) {
		selected = 0;
	}
	
	var tabs = {
		"Top": "index.html",
		"News": "/drupal7",
		"会社概要": "company.html",
		"技術トレーニング": "training.html",
		"技術情報": "techs.html",
		//"スタッフ": "staff.html",
		//"お問い合わせ": "contact.html",
		"アカウント": "signin.html"
	};
	var container = $('<div>').addClass('menu_container');
	var i = 0;
	for ( var label in tabs ) {
		var link = tabs[label];
		var tab = $('<div>').html(label);
		
		if ( selected == i ) {
			tab.addClass('menu-selected');
		} else {
			tab.addClass('menu');
		}
		var tablink = $('<a>').attr("href", link).append(tab);
		container.append(tablink);
		i++;
	}
	target.append(container);	
}

function makeSubMenu(target, menu) {
	var src = location.pathname.split("/").pop();
	var container = $("<div>").addClass("sub_menu_container").css({"height":"1.5em"});
	container.append( $("<div>").addClass("sub_menu_first").html(menu.title));
	
	for ( var title in menu.links ) {
		var m;
		if ( src == menu.links[title] ) {
			m = $("<div>").addClass("sub_menu_selected").html(title);
		} else {
			m = $("<a>").attr("href", menu.links[title]);
			$("<div>").addClass("sub_menu").html(title).appendTo(m);
		}
		container.append( m );
	}
	container.appendTo(target);	
};

function makeCompanyInfoSubMenu(target) {
	makeSubMenu(target,
		{	"title": "サブメニュー", 
			"links": { "概要": "company.html",
					   "マップ": "company_access.html",
					   "設立趣意 (1999年 大竹龍史)": "company_prospectus.html",
					   "設立趣意書に代えて (2007年8月 大竹龍史)": "company_prospectus_2007.html",
					   "沿革": "company_history.html",
					   "個人情報保護方針": "company_policy.html"
			}
		});
};

function makeTrainingSubMenu(target) {
	makeSubMenu(target, 
		{	"title": "トレーニング", 
			"links": { "全コース": "training.html",
					   "Linux": "training_linux.html",
					   "MySQL": "training_mysql.html",
					   "Java": "training_java.html",
					   "Android": "training_android.html",
					   "Web": "training_web.html",
					   "コースリスト": "training_list.html",
					   "お申し込み": "training_order.html"
			}
		});
}

function getVersion() {
	$("#version").html( "ver: " + VERSION + "-" + REVISION);
}

function c(msg) {
	alert(msg);
}

function pullFeed(url, target, n, detail_url) {
	var cache = localStorage[url];
	var cacheTimeKey = url + "-cachedTime";
	var cacheTime = localStorage[cacheTimeKey];

	if(!cacheTime) {
		cacheTime = 0;
	}
	if ( !cache || new Date().getTime() - cacheTime > CACHE_LIMIT_SEC) {
		//$("#center-message").show("slow");
		var loadStatus = $('<div>').html("loading").css({"color":'#bbb'});
		target.append(loadStatus);
		jQuery.ajax( 
			{
				async: true,
				url: url,
				dataType: 'text',
				success: function(xml, status, xhr) {
					loadStatus.hide();
					cache = localStorage[url] = xml;
					localStorage[cacheTimeKey] = new Date().getTime();
					makeFeed( target, cache, detail_url, n);
					//$("#center-message").hide();
				},
				error: function(res, text, h) {
					//alert(res + text + h);
					loadStatus.html("feed connection error ...");
				}
			}
		);
	} else {
		makeFeed( target, cache, detail_url, n);
	}
}

function pullAllCourse() {
	if( typeof localStorage.courses === "undefined" || !localStorage.courses || !localStorage.cachedTime || new Date().getTime() - localStorage.cachedTime > CACHE_LIMIT_SEC ) {
		//console.log( "in" );
		localStorage.cachedTime = new Date().getTime();
		jQuery.ajax({
			async: false,
			url: RESOURCE_URL,
			dataType: 'json',
			success: function(courses) {
				localStorage.courses = JSON.stringify(courses);
			} ,
			error: function(response, textStatus, errorThrown) {
				//console.log(response);
				//alert( errorThrown );
			},
		});
	}
	//return JSON.parse(localStorage.courses);
	return jQuery.parseJSON(localStorage.courses);
}

function pullAllEvent() {	
	if( typeof localStorage.events === "undefined" || !localStorage.events || !localStorage.cachedTimeEvents || new Date().getTime() - localStorage.cachedTimeEvents > CACHE_LIMIT_SEC ) {
		localStorage.removeItem("events");
		localStorage.cachedTimeEvent = new Date().getTime();
		jQuery.ajax({
			async: false,
			url: EVENT_URL,
			dataType: 'json',
			success: function(events) {
				localStorage.events = JSON.stringify(events);
			}, 
			error: function(response) {
				//console.log("error");
				//console.log(response);
			}
		});
	}
	return jQuery.parseJSON(localStorage.events);
}

function include(arr, obj) {
	for ( var i = 0; i < arr.length; i++ ) {
		if (arr[i] == obj){
			return true;
		}
	}
	return false;
}


function separateByComma(num) {
    var money = new String(num).replace(/,/g, "");
    while(money != (money = money.replace(/^(-?\d+)(\d{3})/, "$1,$2")));
    return money;
}

function makeArrayByCourseIds(ids) {
	var array = [];
	var courses = pullAllCourse();
	for (var i in ids) {
		var id = ids[i];
		for (var i in courses){
			if(courses[i].id == id) {
				array.push(courses[i]);
			}
		}
	}
	return array;
}

function getAllCourseTitleFromStorage(target) {
	var courses = pullAllCourse();
	for ( var i = 0; i < courses.length; i++ ) {
		var course = courses[i];
		var link = $("<a>").attr( {href: course.desc_url + "#" + course.id } ).html("[" + course.title + "]&nbsp;");
		link.click( function() { $(this.hash + "-detail-pane").show("normal") } );
		target.append(link);
	}
}

function getCoursesListByCategoryFromStorage(category, target) {
	var courses = pullAllCourse();
	var categorized = [];
	for ( var i = 0; i < courses.length; i++ ) {
		if (include(courses[i].categories, category)) {
			categorized.push( courses[i] );
		}
	}
	
	for ( var i in categorized ) {
		var c = categorized[i];
		var style = "course_list";
		
		if ( i == categorized.length - 1 ) {
			style += "_last";
		}
		
		var container = $('<div class="grid_6 omega" id="' + c.id + '">');
		container.addClass(style);
		
		var linked = $('<a>').attr({href:c.desc_url + "#" + c.id});
		linked
			.append( $('<img class="text-img">').attr({src: c.icon_url}) )
			.append( $('<div class="text-title">').text(c.title) )
			.append( $('<div class="text-summary">').text(c.summary) )
			.append( $('<div class="text-description">').text(c.description) );
		
		container.append(linked);
		target.append(container);
	}
}

function getCoursesByCategory(category) {
	var courses = pullAllCourse();
	var c = [];
	for ( var i = 0; i < courses.length; i++ ) {
		var course = courses[i];
		if ( !include( course.categories, category) ) {
			continue;
		}
		c.push(course);
	}
	return c;
}

function getCourseTitlesByCategoryFromStorage(category, target) {
	var courses = pullAllCourse();
	for ( var i = 0; i < courses.length; i++ ) {
		var course = courses[i];
		if ( !include( course.categories, category) ) {
			continue;
		}
		
		var link = $("<a>").attr( {href: course.desc_url + "#" + course.id } ).html("[" + course.title + "]&nbsp;");
		link.click( function() { $(this.hash + "-detail-pane").show("normal") } );
		target.append(link);
	}
}

function getCoursesByCategoryFromStorage(category, target) {
	var courses = pullAllCourse();
	for ( var i = 0; i < courses.length; i++ ) {
		var course = courses[i];
		if (!include(course.categories, category)) {
			continue;
		}
		
		var leftContainer = $('<div class="grid_5 alpha">');
		var rightContainer = $('<div class="grid_7 omega">');
		var clear = $('<div class="clear"></div>');
		
		with( course ) {
			leftContainer
				.append( $('<img>').attr({ src: icon_url }).addClass('text-img') )
				.append( $('<div>').text(summary) )
				.append( $('<div>').text(description) )
				.append( $('<div>').html("環境: " + environment + "<br>前提: " + prerequisite.join(" ") ) )
				.append( $('<div class="text-price">').text("金額: " + separateByComma(price) + "円 / " + "日数: " + day_length + "日間") );
			
			if ( related_course_ids.length ) {
				var array = makeArrayByCourseIds(related_course_ids);
				var tags = $('<div>').text("関連コース： ").addClass("related_courses");
				for	( var n in array ) {
					var tag = $("<a>").attr({href:array[n].desc_url + "#" + array[n].id }).text( "[" + array[n].title + "]");
					tag.click( function() { $(this.hash + "-detail-pane").show("normal") } );
					tags.append(tag);
				}
				leftContainer.append(tags);
			}
					
			var detailPaneId = id + "-detail-pane";
			var detail = $('<div>').load(detail_url);
			detail.attr("id", detailPaneId);
			detail.addClass("details");
			
			if (location.hash == "#" + id) {
				detail.show();
			} else {
				detail.hide();
			}
			var detailButton = $('<div>詳細</div>').button()
				.click( function() { $(this).next().toggle("normal") } );
			
			target.append( $('<a>').attr({ name: id, id: id }) )
				.append( $('<h3>').text(title + " [" + id + "] ") );

			rightContainer
				.append( detailButton )
				.append( detail );
			
			target
				.append( leftContainer )
				.append( rightContainer )
				.append( clear );
		}
	}
	
	if (location.hash) {
		var hash = $(location.hash);
		var top = hash.position().top;
		window.scroll(0,top);
		
	}
}

function isBlank(str){
    if( str == undefined || str == "" || str == null || str.length == 0) {
        return true;
    }
    return false;
}

function appendStatCounter() {
	var sc_project=7426376;
	var sc_invisible=0;
	var sc_security="e4ddaedb"
	
	var link = $('<div>')
		.css( { float: "right" } )
		.html('<a style="color: #fff;" href="http://statcounter.com/p7426376/summary/?guest=1"><img class="statcounter"src="http://c.statcounter.com/7426376/0/e4ddaedb/0/" alt="counter for tumblr"></a>');
	$('#footer').before(link);
}

function getQueryString() {
	var params = {};
	if (location.search) {
		var ps = location.search.substr(1).split('&');
		for (p in ps) {
			var n = ps[p].split("=")[0];
			var v = ps[p].split("=")[1];
			params[n] = v;
		}
	}
	return params;
}

function findQueryStringByName(name) {
	var queryString = getQueryString();
	return queryString[name];	
}


function drawText(target, title1, title2, title3) {
	var canvas = $('<canvas>');
	if (!title1) title1 = "Java";
	if (!title2) title2 = "Webコンポーネント";
	if (!title3) title3 = "ディベロッパ試験対策";
	
	var ctx = canvas.get(0).getContext("2d");
	var width = 200;
	var height = width * ( 257 / 182 );
	canvas.attr({height:height + 11, width:width + 11});
	with(ctx) {
		fillStyle = "lightgray";
		shadowOffsetX = 5;
		shadowOffsetY = 5;
		shadowBlur = 5;	
		shadowColor = "#888";
		
		fillRect(0, 0, width, height);

		var tb_x = width * 0.075;
		var tb_y = width * 0.075;
		var tb_width = width * 0.85;
		var tb_height = height * 0.4;
		shadowOffsetX = 0;
		shadowOffsetY = 0;
		shadowBlur = 0;	
		shadowColor = "";
		
		fillStyle = "white";		
		fillRect( tb_x, tb_y, tb_width, tb_height );
		
		
		beginPath();
		lineWidth = (width * 0.03) + 0.5;
		moveTo(tb_x, tb_y);
		lineTo(tb_x + tb_width, tb_y);
		moveTo(tb_x, tb_y + tb_height);
		lineTo(tb_x + tb_width, tb_y + tb_height);
		ctx.stroke();
		
		beginPath();
		var font_x = width / 2;
		var font_y = tb_y + 10;
		var font_w = tb_width - 10;
		
		textAlign = "center";
		fillStyle = "black";
		font = (width * 0.06) + "px sans-serif";
		fillText(title1, font_x, font_y, font_w );
		fillText(title2, font_x, font_y + 10, font_w );
		fillText(title3, font_x, font_y + 20, font_w );
		
		
		ctx.fillStyle = "red";
		var ball_x = width * 0.8;
		var ball_y = height * 0.8;
		var ball_r = width * 0.125;
		var grad_x = ball_x * 0.95;
		var grad_y = ball_y * 0.95;
		var grad_r = ball_r;
		
		var ballGradient = createRadialGradient( grad_x, grad_y, 0, grad_x, grad_y, ball_r );
		ballGradient.addColorStop( 0, "white" );
		ballGradient.addColorStop( 0.4, "red" );
		ballGradient.addColorStop( 1.0, "darkred" );
		
		fillStyle = ballGradient;
		shadowOffsetX = 3;
		shadowOffsetY = 3;
		shadowBlur = 3;	
		shadowColor = "#444";
		
		
		ctx.arc( ball_x, ball_y, ball_r, 0, Math.PI * 2, false );
		ctx.fill();
	}
	target.append(canvas);
}


function isNotSpace(str) {
	if(str.match(/\s/)){
		return false;
	}
	return true;
}

function isOnlyAlphabet(str) {
	//str = jQuery.trim(str);
	if(!str.match(/^[a-z]+$/i)) {
		return false;
	}
	return str;
}

function isOnlyNameChar(str) {
	//str = jQuery.trim(str);
	if (str.match( /[\s\w\d\!-\@\[-\`\{-\~]/g ) ){
		return false;
	}
	// http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/e_asia.html#u4e00
	// http://ja.wikipedia.org/wiki/Category:Unicode%E8%A1%A8
	for (var i = 0; i < str.length ; i++) {
		var c = str.charCodeAt(i);
		// http://www.asahi-net.or.jp/~ax2s-kmtn/ref/unicode/uff00.html
		// 半角全角
		if ( c >= 0xFF00 && c <= 0xFFEF) {
			return false;
		}
		// http://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_2000-2FFF
		// 記号 ①□ 等
		if ( c >= 0x2000 && c <= 0x2E7F ) {
			return false;
		}
		// http://ja.wikipedia.org/wiki/Unicode%E4%B8%80%E8%A6%A7_3000-3FFF
		// 郵便番号（〒) 等、
		if ( c >= 0x3000 && c <= 0x3040 ) {
			return false;
		}
	}
	
	return str;
}

function confirmAuth(url) {
	jQuery.ajax({
		type: "POST",
		url: AUTHN_URL,
		async: false,
		data: { "session" : "1", "n" : url },
		xhrFields: { withCredentials: true },
		dataType: "json",
		success: function(result) {
			//alert("success" + result.id);
			console.log(result);
			if (result.id <= 0) {
				location = "/signin.html?next=" + url ;
			} else {
				location = url;
			}
		},
		error: function(result, textStatus, thrown) {
			alert(textStatus);
			console.log(textStatus);
			location = "/signin.html?next=" + url ;
		},
		complete: function() {
			//location = url;
		}
		
	});
}

function formatDateWithYear(s) {
	if ( s.match(/^\d{2,}\/\d+\/\d+$/)) {
		var w = ["日","月","火","水","木","金","土"];
		var d = new Date(s);
		var day = w[d.getDay()];
		return s.replace(/^0/, '&nbsp;').replace(/\/0/, "/&nbsp;") + " (" + day + ")";
	}
	return s;
}

function formatDate(s) {
	if ( s.match(/^\d{2,}\/\d+\/\d+$/)) {
		var w = ["日","月","火","水","木","金","土"];
		var d = new Date(s);
		var day = w[d.getDay()];
		return s.substr(5, 5).replace(/^0/, '&nbsp;').replace(/\/0/g, "/&nbsp;") + " (" + day + ")";
	}
	return s;
}

function formatTime(h) {
	if (h > 1) {
		return h + "日間";
	} else {
		return Math.floor( h * 24 ) + "時間";
	}
}

