/*!
 * Copyright goodsmore <http://goodsmore.net/>
 * version 1.46
 * Dual licensed under the MIT or GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */

/*!
 * オプションの使用例 1
 * var ArticleId = $.getArticleId() ;
 * $( '#IsHeavySeller' ).getMoshimoApi( ArticleId, 'IsHeavySeller', function( el, value ){
 * 		if ( value = 'ヒット実績あり!' ) {
 * 			el.css( 'border', '3px solid red' ) ;
 * 			alert( 'ヒット実績あり! おすすめですよ♪' ) ;
 * 		}
 * 	}, { addclass: 'IsHeavySeller',	duration: 1500 });
 * 
 * オプションの使用例 2
 * var ArticleId = $j.getArticleId() ;
 * $( '#stockstatus' ).getMoshimoApi( ArticleId, 'StockStatus', function( el, value ){
 * 		switch( value ) {
 * 			case '0':
 * 				var img = '<img src="在庫切れの画像url" alt="在庫切れ">' ;
 * 				break;
 * 			case '1':
 * 				var img = '<img src="在庫わずかの画像url" alt="在庫わずか">' ;
 * 				break;
 * 			case '2':
 * 				var img = '<img src="在庫ありの画像url" alt="在庫あり">' ;
 * 				break;
 * 			case '3':
 * 				var img = '<img src="在庫豊富の画像url" alt="在庫豊富">' ;
 * 				break;
 * 		}
 * 		el.html( img ) ;
 * }, { getValue: true });
 * 
 * クロスドメインで利用する場合の javascriptコード例
 * var ArticleId = $.getArticleId() ;
 * $( '#NewIcon' ).getMoshimoApi( ArticleId, 'NewIcon', { password:'パスワード' , ajaxUrl:'http://www.example.jp/moshimo_api/' });
 */

/*!
 * getItemsApiの使用例 1
 * $.getItemsApi({ 'CatchCopy' : '.Catch' ,'StockStatusWord' : '.Stock' });
 * 
 * クロスドメインで利用する場合の javascriptコード例
 * $.getItemsApi({ 'CatchCopy' : '.Catch' ,'StockStatusWord' : '.Stock' } , { password:'パスワード' , ajaxUrl:'http://www.example.jp/moshimo_api/' });
 */

/*!
 * ランキングの表示例
 * 
 * $( '#Ranking' ).getMoshimoRanking( { category : '01' });
 * $( '#Ranking' ).getMoshimoRanking( { word : 'お歳暮' });
 * $( '#Ranking' ).getMoshimoRanking( { tag : '掃除機' });
 * 
 * オプションの使用例
 * $( '#Ranking' ).getMoshimoRanking({
 * 		word                           : 'お歳暮',              // 検索ワード
 * 		tag                            : '掃除機',              // タグ
 * 		category                       : '01,',                 // カテゴリーコード
 * 		except_words                   : '酒',                  // 除外キーワード
 * 		title                          : '%s のランキングTOP5', // タイトル
 * 		len                            : 30,                    // 商品名の文字数 0にすると制限なし
 * 		imageSize                      : 'm',                   // 画像サイズ "s, m, r, l" のいずれかを指定
 * 		addkey                         : 'ShopPrice,StockStatusWord,PopIcon,Summary', // 表示する項目のキーををコンマ（ , ）区切りで指定
 * 		addclass                       : 'ranking',            // 適用する class属性
 * 		col                            : 5,                    // 列数を数字で指定
 * 		duration                       : 0,                    // 数字を大きくすると、フェードインして表示,
 * 		summary_len                    : 100,                  // 商品説明概要の文字数を数字で指定
 * 		preShow:function( el ){                                // 表示される直前に実行されるコールバック関数
 * 			alert( 'ランキング表示するね ちょっと待ってね♪' ) ;
 * 		},
 * 		onAfter:function( el ){                                // 表示が完了した時に実行されるコールバック関数
 * 			alert( 'やった ランキング表示できたよ♪' ) ;
 * 		}
 * });
 * 
 * クロスドメインで利用する場合の javascriptコード例
 * $( '#Ranking' ).getMoshimoRanking( { category : '01' , password:'パスワード' , ajaxUrl:'http://www.example.jp/moshimo_api/' });

/*!
 * MoshimoSearchの表示例
 * 
 * $( '#Search' ).MoshimoSearch({ category : '02' , title : '%s の新着商品' , sortorder : 'newly' , stock_status : 1 });
 * $( '#Search' ).MoshimoSearch( { word : 'お歳暮' , title : '%sの新着商品' , sortorder : 'newly' , stock_status : 1 });
 * $( '#Search' ).MoshimoSearch( { tag : '掃除機' , title : '%sの新着商品' , sortorder : 'newly' , stock_status : 1 });;
 * 
 * オプションの使用例
 * $( '#Search' ).MoshimoSearch({
 * 		word                          : 'お歳暮',         // 検索ワード
 * 		tag                           : '掃除機',         // タグ
 * 		category                      : '01,',            // カテゴリーコード
 * 		except_words                  : '酒',             // 除外キーワード
 * 		sortorder                     : 'newly',          // 並び順
 * 		is_newly                      :  0,               // 0:新着商品以外も含む 1：新着商品のみ
 * 		is_salable                    :  0,               // 0:指定なし 1：ヒット商品のみ
 * 		is_delivery_sameday           :  0,               // 0:指定なし 1：即日配送のみ
 * 		is_free_shipping              :  0,               // 0:指定なし 1：送料無料商品のみ
 * 		stock_status                  :  0,               // 0：在庫切れ 1：在庫わずか 2：在庫あり 3：在庫豊富
 * 		exists_stock                  :  1,               // 0：指定なし 1：在庫あり商品のみ 2：在庫なし商品のみ ※ 指定がある場合、stock_status は無効
 * 		fixed_price_from              :  0,               // 希望小売価格 From
 * 		fixed_price_to                :  0,               // 希望小売価格 To
 * 		default_profit_price_from     :  0,               // 標準利益価格 From
 * 		default_profit_price_to       :  0,               // 標準利益価格 To
 * 		default_profit_rate_from      :  0,               // 標準利益率 From
 * 		default_profit_rate_to        :  0,               // 標準利益率 To
 * 		recommended_sales_price_from  :  0,               // 推奨販売価格 From
 * 		recommended_sales_price_to    :  0,               // 推奨販売価格 To
 * 		minimum_price_from            :  0,               // 最低販売価格 From
 * 		minimum_price_to              :  0,               // 最低販売価格 To
 * 		wholesale_price_from          :  0,               // 卸価格 From
 * 		wholesale_price_to            :  0,               // 卸価格 To
 * 		has_shop_price                :  '',              // registered ：販売価格設定済商品のみ unregistered ：販売価格未設定商品のみ
 * 		field                         :  '',              // 未指定：商品名と説明文から検索 full：商品名と説明文から検索 name：商品名のみから検索
 * 		image_count_from              :  0,               // 画像枚数 From
 * 		image_count_to                :  0,               // 画像枚数 To
 * 		jan_code                      :  '',              // JAN コード
 * 		payment_type                  :  0,               // 0:指定なし 1：クレジット支払のみ 3：クレジット / 代引き
 * 		start_date_from               :  '',              // もしも入荷日付 From YYYYMMDD または YYYY-MM-DD
 * 		start_date_to                 :  '',              // もしも入荷日付 To YYYYMMDD または YYYY-MM-DD
 * 		title                         : '%s の新着商品',  // タイトル
 * 		len                           : 30,               // 商品名の文字数 0にすると制限なし
 * 		imageSize                     : 'm',              // 画像サイズ "s, m, r, l" のいずれかを指定
 * 		addkey                        : 'ShopPrice,StockStatusWord,PopIcon,Summary', // 表示する項目のキーををコンマ（ , ）区切りで指定
 * 		addclass                      : 'search',         // 適用する class属性
 * 		col                           : 5,                // 列数を数字で指定
 * 		duration                      : 0,                // 数字を大きくすると、フェードインして表示,
 * 		summary_len                   : 100,              // 商品説明概要の文字数を数字で指定
 * 		preShow:function( el ){                           // 表示される直前に実行されるコールバック関数
 * 			alert( '新着商品表示するね ちょっと待ってね♪' ) ;
 * 		},
 * 		onAfter:function( el ){                           // 表示が完了した時に実行されるコールバック関数
 * 			alert( 'やった 新着商品表示できたよ♪' ) ;
 * 		}
 * });
 * 
 * クロスドメインで利用する場合の javascriptコード例
 * $( '#Search' ).MoshimoSearch({ category : '02' , password:'パスワード' , ajaxUrl:'http://www.example.jp/moshimo_api/' });
 */
(function($) {
	$.extend({
		getUrlParameters: function(url){
			var vars = [], hash;
			var hashes = url.slice(url.indexOf('?') + 1).split('&');
			for( var i = 0; i < hashes.length; i++ ){
				hash = hashes[i].split('=');
				vars.push( hash[0] );
				vars[hash[0]] = hash[1];
			}
			return vars;
		},
		getUrlParameter: function(url,name){
			return $.getUrlParameters(url)[name];
		},
		getArticleId: function(){
			var article_id = 0
		 	var url = $( 'a[ href *= "/cart/add?"]' ).attr( 'href' ) || '' ;
			if ( url.indexOf( 'article_id=' ) !== -1 ) article_id = parseInt( $.getUrlParameter( url, 'article_id' ) ) ;
			return article_id ;
		},
		number_format: function( num ){
			return ( num >  0 ) ? num.toString().replace( /([0-9]+?)(?=(?:[0-9]{3})+$)/g , '$1,' ) : '' ;
		},
		substr: function( str, len, o ) {
			var defaults = {
				rest: '...'
			};
			var option = $.extend( {},defaults, o );
			if( str.length > len ){
				var cutstring = str.substring( 0, len ) ;
				var byte = countByte(cutstring);
				var tmp = "" ;
				if ( byte < len*2 ) {
				 	for( k=0; k < ( len*2-byte )*2 ; k++) {
						tmp = str.substring( 0,len + k ) ;
						if ( countByte( tmp ) >= len*2 ) {
							break;
						}
					}
				}
				if( tmp ){
					return tmp + option.rest ;
				} else {
					return str.substring( 0, len ) + option.rest;
				}
			} else {
				return str;
			}

			function countByte( str ) {
				var byte = 0;
				for ( j=0; j < str.length; j++ ) {
					str.charCodeAt( j ) < 0x100 ? byte++ : byte += 2 ;
				}
				return byte; 
			}
		},
		getItemsApi: function( selectors, params ){
			var onAfter = null ;
			var o = null ;
			for ( i= 1; i <= 2; i++ ) {
				if ( $.isFunction( arguments[i] ) ) onAfter = arguments[i] ;
				else if ( $.isPlainObject( arguments[i] ) ) o = arguments[i] ;
			}
			if ( $.isPlainObject( selectors ) ) for ( var key in selectors )  {
				$( selectors[ key ] ).getMoshimoApi( key, onAfter, o ) ;
			}
		},
		getMoshimoApi: function( params ){
			var id = 0 ;
			var key = '' ;
			var selector = '' ;
			var onAfter = null ;
			var value = '' ;
			var PerPage = 5 ;
			var ReviewSort = 'date_desc' ;
			var rate = 0 ;
			var o;
			for ( i= 0; i <= 4; i++ ) {
				if ( typeof arguments[i] =='number' ) id = parseInt( arguments[i] ) ;
				else if ( $.isPlainObject( arguments[i] ) ) o = arguments[i] ;
				else if ( typeof arguments[i] =='string' ) key = arguments[i] ;
				else if ( typeof arguments[i] =='object' ) selector = arguments[i] ;
				else if ( $.isFunction( arguments[i] ) ) onAfter = arguments[i] ;
			}
			var option = $.extend( {},defaultOption( 'api' ), o ) ;
			var baseUrl = option.ajaxUrl || base_url() ;
			var url = baseUrl + 'ajax_load.php';
			var dataType = ( option.password =='' ) ? 'json' : 'jsonp' ;
			var showItemData = function ( el, value, json ) {
				var $$ = $( el ) ;
				if ( $$.size() > 0 ) switch( ! option.getValue ) {
					case true:
						$$.hide()
						if ( option.addclass !== null ) $$.addClass( option.addclass ) ;
						$$
							.html( value )
							.fadeIn( option.duration, function () {
								if( $.isFunction( onAfter ) ) onAfter.call( this, $$, value ) ;
							}) ;
						break;
					case false :
						if ( option.addclass !== null ) $$.addClass( option.addclass ) ;
						if( $.isFunction( onAfter ) ) onAfter.call( this, $$, value ) ;
						break;
				}
				if ( key == 'Average' ) $$.addClass( 'average' ) ;
				if ( key == 'Review' ) {
					PerPage = parseInt( json.review_limit ) || 5 ;
					$( '#[ id ^= "ReviewNav_" ]' ).bind( 'click', { el : $$ , id : id }, ReviewNav ) ;
					$( '#[ id ^= "rating" ]' ).bind( 'click', { el : $$ , id : id }, RatingNav ) ;
					ReviewSortNav( $$, id ) ;
					ReviewPerpage( $$, id ) ;
					return ;
				}
			} ;
			var showSozai = function ( el, item_sozai, json ) {
				var $$ = $( el ) ;
				var addclass = option.sozai_addclass || json.sozai_addclass ;
				if ( $$.size() > 0 ) switch( ! option.getValue ) {
					case true:
						if ( $$.size() > 0 && $.isFunction( $.fn.getSozai ) ) {
							$$.getSozai( id, { json: {
									sozai: item_sozai,
									width: parseInt( option.sozai_width ) || parseInt( json.sozai_width ),
									sozai_id: json.sozai_id ,
									addclass: addclass ,
									duration: parseInt( option.sozai_duration ) || parseInt( json.sozai_duration )
								}
							});
						}
						break;
					case false :
						$$.addClass( addclass ) ;
						if( $.isFunction( onAfter ) ) onAfter.call( this, $$, value ) ;
						break;
				}
				return ;
			} ;
			getItemImage = function ( key, data ) {
				var resArray = key.split( '_' ) ;
				return ItemImage( resArray[1], parseInt( resArray[2] ), data )
			} ;
			var getTag = function ( Tags ) {
				var delimiter = '' ;
				for ( var key in Tags )  {
					delimiter = ( value == '' ) ? '' : ',' ;
					value += delimiter + Tags[ key ] ;
				}
				return value ;
			} ;
			var getGroupItem = function ( GroupItem, request ) {
				var addclass = option.GroupItemAddclass || request.GroupItemAddclass ;
				var col = option.GroupItemCol || request.GroupItemCol ;
				var Title = option.GroupItemTitle || request.GroupItemTitle ;
				var len = parseInt( option.GroupItemlen ) || parseInt( request.GroupItemlen ) ;
				var imageSize = option.GroupItemimageSize || request.GroupItemimageSize ;
				var addkey = option.GroupItemaddKey || request.GroupItemaddKey ;
				var item = 1 ;
				for ( var i in GroupItem )  {
					if ( parseInt( i ) >= 0 ) {
						var StockStatus = parseInt( GroupItem[ i ][ 'StockStatus' ] ) ;
						if ( value == ''  && StockStatus > 0 ) value = '<table class="' + addclass + '"><tbody><tr><th colspan="' + col + '" >' + Title + '</th></tr><tr>' ;
						var href = ( option.link_format ==  '' ) ? GroupItem[ i ][ 'ItemHref' ] : option.link_format.replace( '%s', GroupItem[ i ][ 'ArticleId' ] ) ;
						var image = ItemImage( imageSize, 1, GroupItem[ i ]) ;
						var name = ( len > 0 ) ? $.substr( GroupItem[ i ][ 'Name' ], len ) : GroupItem[ i ][ 'Name' ] ;
						if ( StockStatus > 0 ) {
							value = value + '<td style="width: ' + 100 / col + '%;"><a href="' + href + '">' + image + '</a><a href="' + href + '">' + name + '</a>' ;
							value = maekeAddkey( GroupItem[ i ], value, addkey ) ;
							value = ( parseInt( item )%col == 0 ) ? value + '</tr><tr>' : value + '</td>' ;
							item++ ;
						}
					}
				}
				if ( value !== '' ) value = value + '</tr></tbody></table>' ;
				return value ;
			} ;
			var ReviewNav = function ( e ) {
				var offset = parseInt( this.id.slice( 10 ) ) ;
				getReview( e.data.el, e.data.id, offset );
				return false;
			} ;
			var ReviewSortNav = function ( el, ArticleId ) {
				$( '#review_order' )
					.val( ReviewSort )
					.SelectBox({
						textclass : 'SelectBoxText corner-all',
						onAfter:function( select, val ) {
							ReviewSort = val ;
							getReview( el, ArticleId, 0 ) ;
						}
					}) ;
			} ;
			var RatingNav = function ( e ) {
				rate = parseInt( this.id.slice( 6 ) ) ;
				getReview( e.data.el, e.data.id, 0 );
				return false;
			} ;
			var ReviewPerpage = function ( el, ArticleId ) {
				var per_page = parseInt( PerPage )  ;
				var obj = $( '#review_per_page' ) ;
				var label = $( 'optgroup', obj ).attr( 'label' ) ;
				obj
					.val( per_page )
					.SelectBox({
						create:function() {
							$( '#review_per_page_SelectBox_label' )
								.text( label + ' ' + per_page )
								.attr( 'title' , label + ' ' + per_page ) ;
						},
						onAfter:function( select, val ) {
							PerPage = parseInt( val ) ;
							$( '#review_per_page_SelectBox_label' ).text( label + ' ' + per_page ) ;
							getReview( el, ArticleId, 0 ) ;
						}
					}) ;
			} ;
			var getReview = function ( el, ArticleId, offset ) {
				var parameter = 'type=get_review&id=' + ArticleId + '&offset=' + offset + '&rate=' + rate + '&sort=' + ReviewSort + '&per_page=' + PerPage ;
				if ( dataType == 'jsonp' ) parameter = parameter + '&password=' + encodeURIComponent( option.password ) + '&host=' + encodeURIComponent( location.hostname ) ;
				var successCallback = function ( json, status ) {
					if ( status != 'error' && json != '' ){
						var $$ = $( el ) ;
						$$
							.hide()
							.html( json )
							.fadeIn( 1500 ) ;
						var t = $.support.boxModel ? navigator.appName.match(/Opera/) ? 'html' : 'html,body' : 'body' ;
						$( t ).animate({ scrollTop: el.offset().top - 50 }, { duration: 1500 }) ;
						$( '#[ id ^= "ReviewNav_" ]' ).bind( 'click', { el : $$ , id : ArticleId }, ReviewNav ) ;
						$( '#[ id ^= "rating" ]' ).bind( 'click', { el : $$ , id : ArticleId }, RatingNav ) ;
						ReviewSortNav( $$, ArticleId ) ;
						ReviewPerpage( $$, ArticleId ) ;
					}
				} ;
			
				$.ajax({ type: 'GET', url: url, data: parameter, async : true, dataType : dataType, global: false, success : successCallback }) ;
				return false;
			} ;
			var getApi = function ( json, key, selector ) {
				value = '' ;
				switch( typeof json.item_data[ key ] == 'string' ) {
					case true:
						value = json.item_data[ key ] ;
						break;
					case false :
						if ( key.indexOf( 'ItemImage' ) !== -1 ) {
							value = getItemImage( key, json.item_data ) ;
						} else if ( key.indexOf( 'Material' ) !== -1 ) {
							if ( json.item_data[ 'HasMaterial' ] == '1' && $.isFunction( $.fn.getSozai ) ) {
								var $$ = $( selector ) ;
								if ( $$.size() > 0 ) $$.getSozai( id ) ;
							}
						} else if ( key == 'Tag' && $.isPlainObject( json.item_data.Tags ) ) {
							value = getTag( json.item_data.Tags ) ;
						} else if ( key == 'GroupItem' && typeof json.item_data[ key ] == 'object' ) {
							value = getGroupItem( json.item_data.GroupItem, json.option ) ;
						}
						break;
				}
				if ( selector !== '' && key.indexOf( 'Material' ) !== -1 ) showSozai( selector, value, json ) ;
				else if ( selector !== '' ) showItemData( selector, value, json ) ;
				return ;
			} ;
			if ( id > 0 ){
				var parameter = 'id=' + id ;
				if ( option.summary_len !== null  )  parameter += '&summary_len=' + option.summary_len ;
				if ( dataType == 'jsonp' ) parameter = parameter + '&password=' + encodeURIComponent( option.password ) + '&host=' + encodeURIComponent( location.hostname ) ;
				var successCallback = function ( json, status ) {
					if ( typeof json == 'string' ) alert ( json ) ;
					else if ( key !== '' && selector !== '' ) getApi( json, key, selector ) ;
					else if ( $.isPlainObject( json.selectors ) ) for ( key in json.selectors )  {
						getApi( json, key, json.selectors[ key ] ) ;
					}
					return ;
				} ;
			    $.ajax({ type: 'GET', url: url, data: parameter, async : true, dataType : dataType, global: false, success : successCallback }) ;
			}
			return ;
		}
	});
	$.fn.getMoshimoApi = function( params ){
		var article_id;
		var key;
		var onAfter;
		var o;
		for ( i= 0; i <= 3; i++ ) {
			if ( typeof arguments[i] == 'string' ) key = arguments[i] ;
			else if ( typeof arguments[i] == 'number' ) article_id = parseInt( arguments[i] ) ;
			else if ( $.isFunction( arguments[i] ) ) onAfter = arguments[i] ;
			else if ( $.isPlainObject( arguments[i] ) ) o = arguments[i] ;
		}
		var option = $.extend( {},defaultOption( 'api' ), o ) ;
		var get_defined = function( e ) {
			var defined = '' ;
			defined = $( e ).get(0).id ;
			if ( ! defined.match( /_([0-9]+)$/ ) ) {
				var parents = $( e ).parents() ;
				for ( i= 0; i < parents.size(); i++ ) {
					defined = parents.eq(i).get(0).id ;
					if ( defined.match( /_([0-9]+)$/ ) ) break ;
 				}
			}
			return defined ;
		};
		var get_article_id = function( e ) {
			var article_id = 0 ;
			var defined = get_defined( e ) ;
			var id = ( defined !== '' ) ? defined.split( '_' ) : '' ;
			article_id = ( $.isArray( id ) ) ? parseInt( id[ id.length - 1 ] ) : 0 ;
			return article_id ;
		} ;
		return this.each( function(){
			var id = article_id || get_article_id( this ) ;
			$.getMoshimoApi( id, key, this, onAfter, option ) ;
			return ;
		}) ;
	};
	$.fn.getMoshimoRanking = function( o ){
		var type = 'ranking';
		var resArray = requestArray();
		var request = '';
		var option = $.extend( {},defaultOption( type ), o ) ;
		var baseUrl = option.ajaxUrl || base_url() ;
		var url = baseUrl + 'ajax_load.php';
		var dataType = ( option.password =='' ) ? 'json' : 'jsonp' ;
		return this.each( function(){
			var el = $( this ) ;
			var parameter = 'type=' + encodeURIComponent( type );
			for ( i= 0; i < resArray.length; i++ ) {
				if ( resArray[ i ]  == 'word' || resArray[ i ]  == 'tag' || resArray[ i ]  == 'category' ) request = option[ resArray[ i ] ] || definedRequest( el ,  resArray[ i ] ) ;
				else  request = ( option[ resArray[ i ] ] !== null  ) ? option[ resArray[ i ] ] : null ;
				if ( request ) parameter = parameter + '&' + resArray[ i ] + '=' + encodeURIComponent( request ) ;
			}
			if ( dataType == 'jsonp' ) parameter = parameter + '&password=' + encodeURIComponent( option.password ) + '&host=' + encodeURIComponent( location.hostname ) ;
			var successCallback = function ( json, status ) {
				var Arr = optionArray();
				if ( $.isPlainObject( json.option ) ) for ( i= 0; i < Arr.length; i++ ) {
					if ( Arr[ i ] == 'title' ) option[ Arr[ i ] ] = json.option[ Arr[ i ] ] ;
					else if ( option[ Arr[ i ] ] == null ) option[ Arr[ i ] ] = json.option[ Arr[ i ] ] ;
				}
				if ( typeof json == 'string' ) alert ( json ) ;
				else if ( json.item_data ) getItem( el, type, json.item_data, option ) ;
				return ;
			} ;
		    $.ajax({ type: 'GET', url: url, data: parameter, async : true, dataType : dataType, global: false, success : successCallback }) ;
			return ;
		}) ;
	};
	$.fn.MoshimoSearch = function( o ){
		var type = 'search';
		var resArray = requestArray();
		var defaults = defaultOption( type );
		defaults.sortorder  = '';
		var keys = new Array(
			'is_newly',
			'is_salable',
			'is_delivery_sameday',
			'is_free_shipping',
			'stock_status',
			'exists_stock',
			'fixed_price_from',
			'fixed_price_to',
			'default_profit_price_from',
			'default_profit_price_to',
			'default_profit_rate_from',
			'default_profit_rate_to',
			'recommended_sales_price_from',
			'recommended_sales_price_to',
			'minimum_price_from',
			'minimum_price_to',
			'wholesale_price_from',
			'wholesale_price_to',
			'has_shop_price',
			'field',
			'image_count_from',
			'image_count_to',
			'jan_code',
			'payment_type',
			'start_date_from',
			'start_date_to'
		) ;
		for ( i= 0; i < keys.length; i++ ) {
			defaults[ keys[ i ] ]  = '';
		}
		var option = $.extend( {},defaults, o ) ;
		var baseUrl = option.ajaxUrl || base_url() ;
		var url = baseUrl + 'ajax_load.php';
		var dataType = ( option.password =='' ) ? 'json' : 'jsonp' ;
		return this.each( function(){
			var el = $( this ) ;
			var parameter = 'type=' + encodeURIComponent( type );
			for ( i= 0; i < resArray.length; i++ ) {
				if ( resArray[ i ]  == 'word' || resArray[ i ]  == 'tag' || resArray[ i ]  == 'category' ) request = option[ resArray[ i ] ] || definedRequest( el ,  resArray[ i ] ) ;
				else  request = ( option[ resArray[ i ] ] !== null  ) ? option[ resArray[ i ] ] : null ;
				if ( request ) parameter = parameter + '&' + resArray[ i ] + '=' + encodeURIComponent( request ) ;
			}
			for ( i= 0; i < keys.length; i++ ) {
				if ( option[ keys[ i ] ] !== '' ) parameter = parameter + '&' + keys[ i ] + '=' + encodeURIComponent( option[ keys[ i ] ] ) ;
			}
			if ( option.sortorder !== '' ) parameter = parameter + '&sortorder=' + encodeURIComponent( option.sortorder ) ;
			if ( dataType == 'jsonp' ) parameter = parameter + '&password=' + encodeURIComponent( option.password ) + '&host=' + encodeURIComponent( location.hostname ) ;
			var successCallback = function ( json, status ) {
				var Arr = optionArray();
				if ( $.isPlainObject( json.option ) ) for ( i= 0; i < Arr.length; i++ ) {
					if ( Arr[ i ] == 'title' ) option[ Arr[ i ] ] = json.option[ Arr[ i ] ] ;
					else if ( option[ Arr[ i ] ] == null ) option[ Arr[ i ] ] = json.option[ Arr[ i ] ] ;
				}
				if ( typeof json == 'string' ) alert ( json ) ;
				else if ( json.item_data ) getItem( el, type, json.item_data, option ) ;
				return ;
			} ;
		    $.ajax({ type: 'GET', url: url, data: parameter, async : true, dataType : dataType, global: false, success : successCallback }) ;
			return ;
		}) ;
	};
	$.fn.SelectBox = function(o){
		var defaults = {
			labelclass : 'SelectBoxLabel corner-all',
			contentboxclass : 'shadow_box corner-all',
			contentclass : 'SelectBoxContent',
			textclass : 'SelectBoxText',
			duration: 1500,
			timeout: 1000,
			top : 5,
			left : 20,
			create : null,
			onAfter : null
		};
		var option = $.extend( {},defaults, o ) ;
		return this.each(function(){
			var el = $( this ) ;
			var id = this.id + '_SelectBox' ;
			var selected = el.val() ;
			var optgroup = $( 'optgroup', this ) ;
			var str = '<div class="PageNav">' ;
			var val = '' ;
			var label = '' ;
			var _option = '' ;
			var SelectBoxTimer ;
			var make_content = function ( options ) {
				var text = '' ;
				for ( var i=0; i< options.length; i++ ) {
					_option = $( options[i] ) ;
					val = _option.val() ;
					label = _option.text() ;
					text += '<a id="' + id + '_select_' + ( i + 1 ) + '"' + ( ( selected == val ) ? ' class="selected ' + option.textclass + '"' : ' class="' + option.textclass + '"' ) + ' name="' + encodeURIComponent( val ) + '" href="#" title="' + label + '">' + label + '</a>' ;
					if ( _option.get(0).className == 'br' ) text += '</div><div class="PageNav">' ;
				}
				return text;
			} ;
			switch ( optgroup.length > 0 ) {
				case true :
					for ( var e=0; e< optgroup.length; e++ ) {
						val = $( optgroup[e] ).attr( 'label' ) ;
						str += '<div id="' + id + '_optgroup_' + ( e + 1 ) + '" class="optgroup" title="' + val  + '">' + val + '</div>' ;
						var options = $( 'option', optgroup[e] ) ;
						str += make_content( options ) ;
					}
					break;
				case false :
					var options = $( 'option', this ) ;
					str += make_content( options ) ;
					break;
			}
			str += '</div>' ;
			var selected_text = $( 'option:selected', this ).text() ;
			var select = $( '<div id="' + id + '" class="SelectBox"><span id="' + id + '_label" class="' + option.labelclass + '" title="' + selected_text  + '">' + selected_text + '</span><div id="' + id + '_content" class="selectbox_content ' + option.contentboxclass + '" style="display:none;"><div class="' + option.contentclass + '">' + str + '</div></div></div>' ) ;
			select.insertAfter( el.hide() ) ;
			if( $.isFunction( option.create ) ) option.create.call( this, el ) ;
			select.bind( 'click.SelectBox' , function( event ) {
				var obj = $( '#' + id + '_content' ) ;
				var offset = select.offset() ;
				var position = select.position() ;
				var width  = obj.innerWidth() ;
				var scrollTop = document.documentElement.scrollTop || document.body.scrollTop ;
				var clientHeight = document.documentElement.clientHeight || document.body.clientHeight ;
				var contentHeight = $( '#' + id + '_content' ).innerHeight() ;
				var top = ( offset.top - scrollTop + contentHeight < clientHeight ) ? position.top + $( '#' + id + '_label' ).innerHeight() + option.top : position.top - contentHeight - option.top ;
				$( '.selectbox_content:visible' ).fadeOut( option.duration ) ;
				obj
					.css({
						'position': 'absolute' ,
						'top'     : top ,
						'left'    : ( position.left - ( width / 2 ) ) + option.left ,
						'z-index' : 10000
					})
					.fadeIn( option.duration ) ;
			});
			$( '#[ id ^= "' + id + '_select_" ]' ).bind( 'click.SelectBox' , function( event ) {
				var value = this.name || '' ;
				if ( value !== '' ) {
					el.val( value ) ;
					$( '#' + id + '_label' ).text( $( this ).text() ) ;
					$( '#' + id + '_content' ).fadeOut( option.duration ) ;
					if ( $.isFunction( option.onAfter ) ) option.onAfter.call( this, el, value ) ;
				}
				return false;
			});
			$( '#' + id + '_content' )
				.bind( 'mouseover.SelectBox' , function( event ) {
					if ( SelectBoxTimer ) clearTimeout( SelectBoxTimer ) ;
				})
				.bind( 'mouseout.SelectBox' , function( event ) {
					var obj = $( this ) ;
					switch ( event.relatedTarget.id == '' || event.relatedTarget.id.indexOf( 'SelectBox' ) == -1 ) {
						case true :
							SelectBoxTimer = setTimeout( function(){
								obj.fadeOut( option.duration ) ;
							}, option.timeout ) ;
							break;
						case false :
							if ( SelectBoxTimer ) clearTimeout( SelectBoxTimer ) ;
							break;
					}
				});
			el.bind( 'change.SelectBox' , function( event ) {
				var obj = $( 'a[ name ^= "' + $( this ).val() + '" ]' ) ;
				$( '#[ id ^= "' + id + '_select_" ].selected' ).removeClass( 'selected' ) ;
				obj.addClass( 'selected' ) ;
				$( '#' + id + '_label' ).text( obj.text() ) ;
				if ( $.isFunction( option.onAfter ) ) option.onAfter.call( this, el, $( this ).val() ) ;
			});
			$( document ).bind( 'click.SelectBox' , function( event ) {
				if ( event.target.id == '' || event.target.id.indexOf( 'SelectBox' ) == -1 ) $( '.selectbox_content:visible' ).fadeOut( option.duration ) ;
			});
		});
	};
	function base_url(){
		var file_name = 'jquery.moshimo_api.js' ;
		var src = $( 'script[ src *= "' + file_name + '"]' ).attr( 'src' ) ;
		return src.slice( 0, src.indexOf( file_name ) ) ;
	}
	function defaultOption( type ){
		switch( type ) {
			case  'api' :
				return {
					addclass: null,
					duration: 0,
					getValue: false,
					GroupItemAddclass: null,
					GroupItemCol: null,
					GroupItemTitle: null,
					GroupItemlen: null,
					GroupItemimageSize: null,
					GroupItemaddKey: null,
					password: '',
					ajaxUrl: '',
					sozai_width: null,
					sozai_addclass: null,
					sozai_duration: null,
					link_format: '',
					summary_len: null
				};
			default :
				return {
					word: '',
					tag: '',
					category: '',
					except_words: null ,
					title: null ,
					len: null,
					imageSize:null,
					addkey: null ,
					addclass:null ,
					col: null ,
					duration: null,
					preShow: null,
					onAfter: null,
					password: '',
					ajaxUr: '',
					link_format: '',
					summary_len: null
				};
		}
	}
	function requestArray(){
		return new Array(
			'word',
			'tag',
			'category',
			'except_words',
			'title',
			'summary_len'
		) ;
	}
	function definedRequest( el , key ){
		var value = '' ;
		var classname       = ( el.get(0).className !== '' ) ? el.get(0).className.split( ' ' ) : '' ;
		if ( classname.length > 0 ) $.each( classname , function( i, val ) {
			if ( val.indexOf( key + '_' ) !== -1 ) {
				var request = val.split( '_' ) ;
				switch( key ) {
					case 'category':
						value = ( request[1].match( /^([0-9a-zA-Z]+)$/ ) ) ? request[1] : '' ;
						break;
					default:
						value = request[1] ;
				}
				return false ;
			}
		});
		return value ;
	}
	function optionArray(){
		return new Array(
			'title',
			'len',
			'imageSize',
			'addkey',
			'addclass',
			'col',
			'duration'
		) ;
	}
	function ItemImage( s, number, data ){
		var name = data.Name ;
		switch( s ) {
			case 's':
				var size = 58 ;
				break;
			case 'm':
				var size = 80 ;
				break;
			case 'r':
				var size = 150 ;
				break;
			case 'l':
				var size = 300 ;
				break;
		}
		var image = ( number <= parseInt( data.ImageCount ) ) ? 'http://image.moshimo.com/item_image/' + data.ImageCode + '/' + number + '/' + s + '.jpg'  : '' ;
		return ( image !== '' ) ? '<img class="img" src="' + image + '" alt="' + name + '" title="' + name + '" height="' + size + '" width="' + size + '">'  : '' ;
	}
	function maekeAddkey( data, value , request ) {
		var val ;
		var addkey = request.split( ',' ) ;
		if ( addkey[ 0 ] !== '' ) for ( i= 0; i < addkey.length; i++ ) {
			val = '' ;
			var key = $.trim( addkey[ i ] ) ;
			if ( typeof data[ key ] == 'string' ) val = data[ key ] ;
			if ( val !== '' && val.indexOf( '<img' ) == -1 ) value = value + '<p class="item item_' + key + '">' + val + '</p>' ;
			else if ( val !== '' ) value = value + '<div class="icon">' + val + '</div>' ;
		}
		return value ;
	}
	function showItem( el, value, option ) {
		var $$ = $( el ) ;
		$$
			.hide()
			.html( value )
			.addClass( option.addclass ) ;
		$( 'td', $$ ).css({ 'width': 100 / option.col + '%' }) ;
		if( $.isFunction( option.preShow ) ) option.preShow.call( this, $$, value ) ;
		$$.fadeIn( option.duration, function () {
			if( $.isFunction( option.onAfter ) ) option.onAfter.call( this, $$, value ) ;
		}) ;
		return ;
	}
	function getItem( el, type, data, option ) {
		var value = '' ;
		for ( var i in data ) {
			if ( parseInt( i ) >= 0 ) {
				if ( value == '' ) value = '<table><tbody><tr><th colspan="' + option.col + '">' + option.title + '</th></tr><tr>' ;
				var href = ( option.link_format ==  '' ) ? data[ i ][ 'ItemHref' ] : option.link_format.replace( '%s', data[ i ][ 'ArticleId' ] ) ;
				var image = ItemImage( option.imageSize, 1, data[ i ] ) ;
				if ( type == 'ranking' ) var rank = parseInt( i ) + 1 ;
				var name = ( parseInt( option.len ) > 0 ) ? $.substr( data[ i ][ 'Name' ], option.len ) : data[ i ][ 'Name' ] ;
				value = value + '<td>' ;
				if ( type == 'ranking' ) value = value + '<div class="rank' + rank + '">' + rank + '&#20301;</div>' ;
				value = value + '<a href="' + href + '">' + image + '</a><a href="' + href + '">' + name + '</a>' ;
				value = maekeAddkey( data[ i ], value, option.addkey ) ;
				value = ( ( parseInt( i ) + 1 )%option.col == 0 ) ? value + '</tr><tr>' : value + '</td>' ;
			}
		}
		if ( value !== ''  ) {
			value = value + '</tr></tbody></table>' ;
			showItem( el, value, option ) ;
		}
	}
})(jQuery);

