var SynkiUrlBuilder = function(resource_key) {

	var request_my = false;

	// 현재 url
	var _cur = new SynkiUrlParser();

	// 없을 수도 있는... 
	var _nullable = {"container":true, "container_key":true, "action":true, "action_key":true, "sub_action":true, "sub_action_key":true, "else":true}

	// 액션과 서브액션에 올 수 있는 값들.
	var key_search = {
		"container":["ws", "my", "offline_revs_for_diff", "login"],
		"action":["search", "page", "pages", "ws_watchlist", "watchlist", "users", "user", "ws_attachments", "stand_alone", "ws_tag", "group", "membership"],
		"sub_action":["tag", "attachment", "revision", "permission"],
		"else":["anchor", "query"]
	}

	// 
	var upper_level_key = {"action":"container_key", "action_key":"container_key", "sub_action":"action_key"};

	// 서브액션이 누구에게 속해있는지..
	var parent_key_of_sub_action = {"search":"ws", "page":"ws", "pages":"ws", "ws_watchlist":"ws", "ws_attachments":"ws", "ws_tag":"ws", "users":"ws", "group":"ws", "membership":"ws", "tag":"pages", "attachment":"pages", "revision":"pages", "permission":"pages", "anchor":"", "query":""}

	// 넘겨받은 resource_key 에 따른 액션
	var action_by_key = {"login":"/login", "offline_revs_for_diff":"/revs", "page":"/pages/", "user":"/users/", "group":"/groups/", "membership":"/memberships/", "watchlist":"/my/watchlist/", "ws_watchlist":"/watchlist/", "tag":"/tags/", "revision":"/revs/", "attachment":"/files/", "ws_attachments":"/files/", "permission":"/permissions/", "anchor":"#", "query":"?"};

	// url 순서입니다아 
	var _url_positions = ["wiki", "pure_host", "container", "container_key", "action", "action_key", "sub_action", "sub_action_key", "else"];

	var _url = "";
	var _value = "";
	var _key = "";
	var _prural_key = "";

	for(var iu=0; iu<_url_positions.length; iu++) {

		_cur_position = _url_positions[iu];
		if(_cur_position in _nullable) {

			if(key_search[_cur_position]) {

				for(var iks=0; iks<key_search[_cur_position].length; iks++) {

					if(resource_key[key_search[_cur_position][iks]]) {

						// YES!, I feel sorry bout these unreadable lines. -_-;
						_value = (action_by_key[key_search[_cur_position][iks]]) ? action_by_key[key_search[_cur_position][iks]] : "/" + key_search[_cur_position][iks] + "/";

						var _semi_action_patt = /^;/
						if(_semi_action_patt.test(resource_key[key_search[_cur_position][iks]])) {

							_value = _value.replace(/\/$/g,"");
							_value += resource_key[key_search[_cur_position][iks]];
						}
						else {

							_value += (resource_key[key_search[_cur_position][iks]] == " ") ? "" : resource_key[key_search[_cur_position][iks]];
							//_value += resource_key[key_search[_cur_position][iks]];
						}

						_key = parent_key_of_sub_action[key_search[_cur_position][iks]]
						_prural_key = parent_key_of_sub_action[key_search[_cur_position][iks]]
						if(_key && _key != "ws") { _key = _key.replace(/s$/,""); };
						if(parent_key_of_sub_action[key_search[_cur_position][iks]] && !resource_key[_key]) { 

							_value = "/" + _prural_key + "/" + _cur[upper_level_key[_cur_position]] + _value;
						}

						if(parent_key_of_sub_action[_key]  && !resource_key[_key] && !resource_key[parent_key_of_sub_action[_key]]) {

							_value = "/" + parent_key_of_sub_action[_key] + "/" + _cur[upper_level_key[upper_level_key[_cur_position]]] + _value;
						}
					}
				}

				_url += _value;
				_value = "";
			}

		} else {

			_url += (resource_key[_cur_position]) ? resource_key[_cur_position] : _cur[_cur_position];
			_url += (iu==0) ? "." : "/";
		}

	}

	_url = _url.replace(/\/+/g,"/");
	_url = _url.replace(/(\/|\/.?\s+)$/g,"");

	return if_offline_requires_different_url(_url);
}

var SynkiUrlParser = function(_specific_url) {
	// container 자리에 올 수 있는 값들.
	var _container = ["ws", "my"];

	// action 자리에 올 수 있는 값들.
	var _actions = ["pages", "watchlist", "attachments", "users"];

	// sub_action 자리에 올 수 있는 값들.
	var _sub_actions = ["files", "tags", "revisions"]

	// 호스트네임 뒤 / 시작 후 순서대로 적어주삼
	//var _path_positions = ["ws", "ws_name", "action", "action_key", "sub_action", "sub_action_key"];
	var _path_positions = ["container", "container_key", "action", "action_key", "sub_action", "sub_action_key"];

	if(_specific_url) {

		_url = parseUrl(_specific_url);

		this.url = _specific_url;
		this.protocol = _url.protocol;
		this.hostname = _url.host;
		var _port =  _specific_url.match(/(:[0-9]+)($|\/)/);
		this.port = (_port) ? _port[1] : null;	
		this.pathname = _url.path.replace(/;.+/,"");
		this.search = _url.hash;
		this.query = {};
		this.hash = _url.anchor;

	}
	else {

		this.url = location.href;
		this.protocol = location.protocol;
		this.hostname = location.hostname;
		this.port = location.port;
		this.pathname = location.pathname;
		this.search = location.search;
		this.query = {};
		this.hash = location.hash;
	}

	var _wiki = this.hostname.split(".",1);
	this.wiki = _wiki[0];
	this.wiki_name = this.wiki;
	this.origin = this.protocol + "//" + this.hostname;
	//this.pure_host = this.hostname.replace(this.wiki_name + ".", "");
	_pure_host = (this.port) ? BASE_DOMAIN + ":" + this.port : BASE_DOMAIN
	this.pure_host = _pure_host.replace(/:+/,":");

	var _path= this.pathname.substring(1).split("/");

	// spread pathname
	for(var ipp=0; ipp<_path_positions.length; ipp++) {
		this[_path_positions[ipp]] = (_path[ipp]) ? _path[ipp] : null;
	}

	// container_key
	for(var ic=0; ic<_container.length; ic++) {
		if(this.container == _container[ic]) {
			//_key = _container[ic].replace(/s$/, "") + "_name";
			_key = _container[ic] + "_name";
			this[_key] = decodeURI(this.container_key);
		}
	}

	// action_key
	for(var ia=0; ia<_actions.length; ia++) {
		if(this.action == _actions[ia]) {
			_key = _actions[ia].replace(/s$/, "") + "_name";
			this[_key] = decodeURI(this.action_key);
		}
	}

	// sub_action_key
	for(var is=0; is<_sub_actions.length; is++) {
		if(this.sub_action == _sub_actions[is]) {
			_key = _sub_actions[is].replace(/s$/, "") + "_name";
			this[_key] = decodeURI(this.sub_action_key);
		}
	}

	// query
	if(this.search) {
		var _q = this.search.replace(/^\?/,"").split("&");
		for(var iq=0; iq<_q.length; iq++) {

			var _kv = _q[iq].split("=");
			this.query[_kv[0]] = decodeURI(_kv[1]);
		}
	}

}

var Synki_LocalDB_Schema = {
	"workspaces": {
		"id": "Integer()",
		"title": "Varchar()",
		"wiki_id": "Integer()",
		"wiki_name": "Varchar()",
		"index_page_id": "Integer({default_value:0})",
		"created_at": "Timestamp()",
		"updated_at": "Timestamp()",
		"downloaded": "Varchar({default_value:'false'})"
	},

	"pages": {
		"id": "Integer()",
		"title": "Varchar()",
		"workspace_id": "Integer()",
		"revisions_count": "Integer()",
		"owner_id": "Integer()",
		"owner_login": "Varchar()",
		"state": "Varchar()",
		"last_user_id": "Integer()",
		"last_user_login": "Varchar()",
		"last_updated_at": "Timestamp({default_value:'CURRENT_TIMESTAMP'})",
		"created_at": "Timestamp({default_value:'CURRENT_TIMESTAMP'})",
		"updated_at": "Timestamp({default_value:'CURRENT_TIMESTAMP'})",
		"local_created": "Varchar({default_value:'false'})",
		"local_updated": "Varchar({default_value:'false'})",
		"local_deleted": "Varchar({default_value:'false'})",
		"uploaded": "Varchar({default_value:'false'})",
		"upload_integrity": "Varchar({default_value:'false'})"
	},

	"revisions": {
		"id": "Varchar({primary_key:true})",
		"version": "Integer()",
		"content": "Text()",
		"page_id": "Integer()",
		"user_id": "Integer()",
		"user_login": "Varchar()",
		"workspace_id": "Integer()",
		"diff": "Varchar()",
		"created_at": "Timestamp({default_value:'CURRENT_TIMESTAMP'})",
		"local_only": "Varchar({default_value:'false'})"
	},

	"tags": {
		"id": "Integer()",
		"name": "Varchar()",
		"local_created": "Varchar({default_value:'false'})"
	},

	"page_tags": {
		"id": "Integer({primary_key:true})",
		"workspace_id": "Integer()",
		"page_id": "Integer()",
		"tag_id": "Integer()",
		"tag_name": "Varchar()",
		"local_created": "Varchar({default_value:'false'})",
		"local_updated": "Varchar({default_value:'false'})",
		"local_deleted": "Varchar({default_value:'false'})",
		"uploaded": "Varchar({default_value:'false'})",
		"upload_integrity": "Varchar({default_value:'false'})"
	},

	"users": {
		"id": "Integer()",
		"email": "Varchar()",
		"first_name": "Varchar()",
		"language": "Varchar()",
		"last_name": "Varchar()",
		"login": "Varchar()",
		"role": "Varchar()",
		"timezone": "Varchar()"
	},

	"attachments": {
		"id": "Integer({primary_key:true})",
		"file_name": "Varchar()",
		"file_size": "Integer()",
		"page_id": "Integer()",
		"page_title": "Varchar()",
		"user_id": "Integer()",
		"user_login": "Varchar()",
		"workspace_id": "Integer()",
		"wiki_id": "Integer()",
		"created_at": "Timestamp()",
		"updated_at": "Timestamp()"
	},

	"permissions": {
		"id": "Integer({primary_key:true})",
		"type": "Varchar()",
		"resource_id": "Integer()",
		"permission": "Varchar({default_value: '000'})"
	},

	"watched_pages": {
		"id": "Integer()",
		"user_id": "Integer()",
		"user_login": "Varchar()",
		"page_id": "Integer()",
		"page_title": "Varchar()",
		"workspace_id": "Integer()",
		"wiki_id": "Integer()",
		"created_at": "Timestamp()",
		"updated_at": "Timestamp()",
		"local_created": "Varchar({default_value:'false'})",
		"local_updated": "Varchar({default_value:'false'})",
		"local_deleted": "Varchar({default_value:'false'})",
		"uploaded": "Varchar({default_value:'false'})",
		"upload_integrity": "Varchar({default_value:'false'})"
	},

	"incoming_links": {
		"id": "Integer({primary_key:true})",
		"workspace_id": "Integer()",
		"page_id": "Integer()",
		"page_title": "Varchar()",
		"referer_id": "Integer()",
		"referer_title": "Varchar()"
	},

	"schema_version": {
		"id": "Integer()",
		"version": "Integer()"
	},

	"application_version": {
		"id": "Integer()",
		"version": "Integer()"
	}
}
