(function($){	 	
	var model3D = function() {
		var
			version = '1.0.2' // Current version
			,model = 'model3D'
			,model_id = 'mod3DId'
			,png = '/text/jplugins/model3D/1.png.gif' // прозрачное изображение в 1px
			,layers_dir = '/upload/images/'
			,img_round = '/text/jplugins/model3D/round.gif'
			,shadow_png = 'shadow_layer.png'
			,shadow_png_hover = 'shadow_layer_hover.png'					
//				,tpl = '<div style="position: relative;width:300px;height:500px;" class="'+model+'"><div class="'+model+'_layers"></div><div class="'+model+'_mapping"><div class="'+model+'_window"><div class="'+model+'_point"></div><div class="'+model+'_line"></div><div class="'+model+'_text"></div></div><img usemap="#a1" class="'+model+'_mapping_image" src="'+png+'" alt="" /></div><map name="a1" id="a1" class="'+model+'_map"></map></div>'
			//,tpl = '<div class="'+model+'"><div class="'+model+'_visual"><div class="'+model+'_window"><div class="'+model+'_point"><img src="round.gif" alt="" /></div><div class="'+model+'_line">.</div><div class="'+model+'_text"></div></div><div class="'+model+'_layers"></div><div class="'+model+'_mapping"></div><div class="'+model+'_layers_name"></div></div></div>'
			,tpl_global = '<div class="'+model+'"><div class="'+model+'_visual"></div></div>'
			,tpl = '<div class="'+model+'_window" style="display:none;"><div class="'+model+'_point"><img src="'+img_round+'" alt="" /></div><div class="'+model+'_line">.</div><div class="'+model+'_text"></div></div><div class="'+model+'_mini_windows"></div><div class="'+model+'_layers"></div><div class="'+model+'_mapping"></div><div class="'+model+'_layers_name"></div>'
			//,tpl_mini_window = '<div class="'+model+'_mini_window_"><div class="'+model+'_point"><img src="'+img_round+'" alt="" /></div><div class="'+model+'_line">.</div><div class="'+model+'_text"></div></div>'
			,defaults = {
				id:null // id общего блока
				,pointers:[[4, 41], [60, 100], [277, 67]] // координаты верхний углов у слоя
				,x:0 
				,y:0 
				,w:277 
				,h:0 // высчитывается
				,z:15 // расстояние между слоями
				,count:0 // количество слоёв
				,active_id:null // активный слой
				,imgW:277 // ширина изображения
				,imgH:98 // высота слоя в 1 px;
				,zIndexFirst:1000
				,block_paddingLeft:68
				,block_events:false
				,line_width:135 // Ширина линии для окна описания
				,line_mini_width:50 // Ширина мини линии для окна с цифрой слоя
				,text_width:450 // Ширина текстового блока для окна описания				
				,layers_div_tite:'Наведите на любой слой и нажмите левый клик'
				,layers:{} // Информация по слоям
				
			}
			/*
			*	Проверяем наличие необходимых опций и их валидность
			*/
			,setOptinons = function(that, opt){
				var check = 0;									
				if(typeof opt.layers == 'object'){
					check = 1;
					/*
					opt.count = opt.layers.length;
					if(opt.count > 0){
						opt.x = that.attr('offsetLeft');
						opt.y = that.attr('offsetTop');
						check = 1;
					}
					*/ 
				}
				var options = $.extend({}, opt);
				return check ? options : false;
			}
			/*
			*	Рендер всего модуля
			*/
			,renderScheme = function(that, options, id){
				//$('#'+id).remove();
				var visual = $('.'+model+'_visual', that);
				visual.length ? visual.html('') : $('#'+id).remove();
				tplRender(that, options, id);
				var top = layersRender(that, options, id);					
				mapRender(that, options, id);
				miniWindowsRender(that, options, id);

				//alert(top)
				//$('.'+model+'_mapping', that).css({'width':options.imgW, 'height':top+options.imgH, 'left':options.x, 'top':options.y});
				$('.'+model+'_mapping_image', that).css({'width':options.imgW*1+options.block_paddingLeft, 'height':top+options.imgH});
				if(($.browser.msie && $.browser.version=="6.0")){
					$('.'+model+'_layers_name', that).css({marginTop:top+options.imgH+20});
				}
				//$('#'+id+'_map_name', that).css({'width':options.imgW+'px', 'height':top+options.imgH+'px', 'left':options.x, 'top':options.y});

				// для ie6 pngfix
				if($.browser.msie && $.browser.version=="6.0"){
					//alert(1)		
					$('img[src$=.png]', that).pngfix();
					//$('img.png', that).pngfix();
					//alert(1)
				}															
			}
			/*
			*	Прорисовываем tpl и прописываем параметры
			*/
			,tplRender = function(that, options, id){					
				//<div class="'+model+'"><div class="'+model+'_visual">
				var visual = $('.'+model+'_visual', that);
				if(!visual.length){					
					var cal_global = $(tpl_global).attr('id', id);
					cal_global.appendTo(that);
					visual = $('.'+model+'_visual', that);
				}
				else visual.html('');
			
				//var tmp_tpl = visual.length ? tpl : '<div class="'+model+'"><div class="'+model+'_visual">'+tpl+'</div></div>';
				var cal = $(tpl)
					.find('.'+model+'_layers').attr('title', options.layers_div_tite).css({'paddingLeft':options.block_paddingLeft}).end()
					.find('.'+model+'_mapping').css({zIndex:options.zIndexFirst+20}).end()
					.find('.'+model+'_point').css({zIndex:options.zIndexFirst+1}).end()
					.find('.'+model+'_line').css({zIndex:options.zIndexFirst+1}).end()
					.find('.'+model+'_text').css({zIndex:options.zIndexFirst+1}).end()						
					.find('.'+model+'_map').attr('id', id+'_map_name').attr('name', id+'_map_name').end()
					//.find('.'+model+'_mapping_image').attr('usemap', '#'+id+'_map_name').css({zIndex:options.zIndexFirst+10}).end();
				//alert(cal.find('.'+model+'_map').attr('name'))	
				cal.appendTo(visual).show();
				$('.'+model+'_layers').attr('title', options.layers_div_tite).css({'paddingLeft':options.block_paddingLeft});
				return cal;					
			}
			/*
			*	Рендер слоёв и блока названий слоёв
			*/
			,layersRender = function(that, options, id){
				//'+model+'_layers_name
				var layers_html = [], layers_name_html = [], layers = options.layers, sumTop = 0, top = 0;	
				var count = options.layers.length;
				var zIndex = options.zIndexFirst*1;
				zIndex;
				for(var i = 0; i < count; i++){
					sumTop += i>0 ? layers[i].h*1+options.z*1 : layers[i].h*1;
					top += i>0 ? layers[i-1].h*1+options.z*1 : 0;
					layers_html.push('<div class="'+model+'_layer" style="position:absolute;top:'+top+'px; z-index:'+(--zIndex)+'"><img class="layer_img_'+i+'" src="'+layers_dir+options.layers[i].src+'" alt="" /></div>');
					layers_name_html.push('<div id="'+id+'_layer_name_'+i+'" class="'+model+'_layer_name">'+(i+1)+'. <span>'+layers[i].name+'</span></div>');
					/*
					if(i>0){
						layers_html.push('<div class="'+model+'_layer" style="position:absolute;top:'+(top+1)+'px; z-index:'+(options.zIndexFirst*1-i)+'"><img class="layer_img_shadow_'+i+'" src="'+layers_dir+shadow_png+'" alt="" /></div>');
					}	*/					
					layers_html.push('<div class="'+model+'_layer" style="position:absolute;top:'+(top*1+layers[i].h*1+options.z*1-1)+'px; z-index:'+(--zIndex*1)+'"><img class="layer_img_shadow_'+i+'" src="'+layers_dir+shadow_png+'" alt="" /></div>');
					// Прелоад померкнувшего изображения слоя
					preLoad(layers_dir+layers[i].src_hover);
				}
				$('.'+model+'_layers', that).html(layers_html.join(''));
				$('.'+model+'_layers_name', that).css({width:options.imgW*1+options.block_paddingLeft}).html(layers_name_html.join(''));
				return sumTop;
			}
			,mapRender = function(that, options, id)
			{
				// Короткие названия переменных
				var pointers = options.pointers;
				var count = options.layers.length;
				var layers = options.layers;
				// Дефолтные x
				var x1 = pointers[0][0]*1; // x левой точки
				var x2 = pointers[1][0]*1; // x центральной точки
				var x3 = pointers[2][0]*1; // x правой точки
				var y1 = pointers[0][1]*1; // x левой точки
				var y2 = pointers[1][1]*1; // x центральной точки
				var y3 = pointers[2][1]*1; // x правой точки
				var z = options.z; // константный отступ между слоями
				$('.'+model+'_html_map', that).html(''); // Очистка map	
				var arr = [];
				var H = sumH = 0;
				var area = [];
				var map_name = id+'_map_name';
				if($('#'+map_name).length)$('#'+map_name).attr('id', '1').attr('name', '1').remove();// for google hrome
				for(var i=0; i<count; i++){
					var h = layers[i].h*1;
					sumH += h*1+z*1;
					H = i>0 ? sumH*1-z*1 : h*1;
					// Просчёт координат точки наложения "точки" =)
					layers[i].point = [];
					layers[i].point[0] = parseInt(x1+(x2-x1)/3);
					layers[i].point[1] = parseInt(y1+H-h/2+z+z/2);
					// Просчёт координат полигона
					// Если не первый слой
					if(i > 0){
						arr = [x1+options.block_paddingLeft, y1+H, x2+options.block_paddingLeft, y2+H, x3+options.block_paddingLeft, y3+H, x3+options.block_paddingLeft, y3+H-h-z, x2+options.block_paddingLeft, y2+H-h-z, x1+options.block_paddingLeft, y1+H-h-z];
					}else{
						arr = [x1+options.block_paddingLeft, y1+H, x2+options.block_paddingLeft, y2+H, x3+options.block_paddingLeft, y3+H, x3+options.block_paddingLeft, 0, x3-20+options.block_paddingLeft, 0, x1+options.block_paddingLeft, y1+H-h, x1+options.block_paddingLeft, y1+H];
					}
					area.push('<area id="'+id+'_map_layer_'+i+'" class="'+model+'_map_layer" shape="poly" coords="'+arr.join(',')+'" href="#" />');					
				} 
				//document.getElementById(id+'_map_name').innerHTML = area.join(''); // глюк, jquery тут не катит
				//alert('<map id="'+id+'_map_name" name="'+id+'_map_name">'+area.join('')+'</map>')
				//alert(area.join(''));
				var map = $('<map id="'+map_name+'" name="'+map_name+'">'+area.join('')+'</map>').css({display:'block'}).appendTo('#'+id);
				var model_mapping = $('.'+model+'_mapping', that);
				//model_mapping.html(model_mapping.html()+'<img style="" usemap="#'+map_name+'" class="'+model+'_mapping_image" src="'+png+'" alt="" />');
				$('<img style="z-index:'+(options.zIndexFirst+20)+'" usemap="#'+map_name+'" class="'+model+'_mapping_image" src="'+png+'" alt="" />').appendTo(model_mapping);
				//$('#'+id+'_map_name', that).attr('innerHTML', area.join(''))
			}
			,miniWindowsRender = function(that, options, id){
				// Короткие названия переменных
				var pointers = options.pointers;
				var count = options.layers.length;
				var layers = options.layers;
				var miniWindows = [];
				var miniWindows_parent = $('.'+model+'_mini_windows', that);
				for(var i=0; i<count; i++){
					miniWindows.push('<div id="'+id+'_mini_window_'+i+'" class="'+model+'_mini_window"><div class="'+model+'_point"><img src="'+img_round+'" alt="" /></div><div class="'+model+'_line">.</div><div class="'+model+'_round">'+(i+1)+'</div></div>');					
					var point = {'left':options.layers[i].point[0]*1+options.block_paddingLeft, 'top':options.layers[i].point[1], 'display':'block'};
					var line = {'left':parseInt(point.left)-options.line_mini_width, 'top':parseInt(point.top)+2, width:options.line_mini_width, 'display':'block'};
					var round = {'left':parseInt(line.left)-18, 'top':parseInt(line.top)-9, 'display':'block'};
					var el = $(miniWindows[i]).css({'zIndex':options.zIndexFirst+1021, 'position':'absolute'})
					.find('.'+model+'_point').css(point).end()
					.find('.'+model+'_line').css(line).end()
					.find('.'+model+'_round').css(round).end()
					el.appendTo(miniWindows_parent);					
				}								
			}
			/*
			 * Показ блока с текстом
			 */
			,showWindow = function(that, options){			
				var id = options.active_id;
				// Скрываем цифру слоя
				//$('.'+model+'_mini_window_'+id).hide();
				var window = $('.'+model+'_window', that);
				// Прорисовка точки
				var point = {'left':options.layers[id].point[0]*1+options.block_paddingLeft, 'top':options.layers[id].point[1]};
				$('.'+model+'_point', window).css(point).show();
				// Прорисовка линии
				var line = {'left':parseInt(point.left)-options.line_width, 'top':parseInt(point.top)+2, width:options.line_width};
				$('.'+model+'_line', window).css(line).show();
				// Прорисовка блока с текстом					
				var text = {'left':parseInt(line.left)-1-options.text_width, 'top':parseInt(line.top)-10, width:options.text_width};
				$('.'+model+'_text', window).css(text).html('<div class="'+model+'_text_name"><div class="'+model+'_round" style="float:left;">'+(id*1+1)+'</div><div style="padding-left:30px;">'+options.layers[id].name+'</div><div style="clear:both;"></div></div>'+options.layers[id].text).show();	
				// Показ блока									
				window.show();	
			}
			/*
			 * Прелоад нужных изображений
			 */				
			,preLoad = function(src){					
				var image = new Image();
				image.src = src;					
			}
			,changeImage = function(that, el, src){
				if($.browser.msie && $.browser.version<="6.0"){
					//Достаём src изображения
					var element = $('span'+el, that);
					if(element.length > 0){
						var el_style = element.attr('style');
						//var matches = el_style.match(/src[^"]/g);
						//alert(matches.length)
						el_style = el_style.replace(/src=([^;]+)/i, 'src='+layers_dir+src);
						element.attr('style', el_style).show();
					}
				}
				else{
					var element = $(el, that);
					if(element.length > 0){					
						element.attr('src', layers_dir+src).show();
					}
				}
			}
			,mouseOut = function(that, options){
				if(options.active_id == null){
		    			for(var i=0; i<options.layers.length; i++)
			    			{
				    				changeImage(that, '.layer_img_'+i, options.layers[i].src);
				    				//$('.layer_img_'+i, that).attr('src',options.layers[i].src);
				    				changeImage(that, '.layer_img_shadow_'+(i+0), layers_dir+shadow_png);
				    				//$('.layer_img_shadow_'+i-1, that).hide();
				    				//$('.layer_img_shadow_'+i, that).attr('src',shadow_png);
			    			}						
				}
			}
			
		return {
			init: function(opt){
				opt = $.extend({}, defaults, opt||{});
				// Прелоад померкнувшей тени
				preLoad(layers_dir+shadow_png_hover);
				
				return this.each(function () {
 					var that = $(this);
					if (!that.data(model_id)) {
						var options = setOptinons(that, opt);
						if(options !== false){
							that.css({position: 'relative'});
 							var id = model+'_' + parseInt(Math.random() * 1000);
 							that.data(model_id, id);
 							//var cal = $('#'+that.data(model_id));
 							renderScheme(that, options, id); 							
 							if((!$.browser.msie || $.browser.version>"6.0")){
 								if(!options.block_events){
		 							// При наведении на любой слой map
		 							$('.'+model+'_map_layer, .'+model+'_layer_name, .'+model+'_mini_window', that).livequery('mouseover', function(e){
			 							//$(this).addClass(model+'_area_over');
		 								e.preventDefault();		 								 							
										var layer_id = $(this).attr('id').split('_')[4]*1;
										$('#'+id+'_map_layer_'+layer_id+', #'+id+'_layer_name_'+layer_id).addClass(model+'_area_over');								
										var old_active_id = null;
										old_active_id = options.active_id; 
										//$('.'+model+'_mini_window_'+old_active_id).show();
										options.active_id = layer_id;
										// Скрываем слой, который был активный
										for(var i=0; i<options.layers.length; i++){
											if(old_active_id == null || old_active_id == i){
												changeImage(that, '.layer_img_'+i, options.layers[i].src_hover);
												changeImage(that, '.layer_img_shadow_'+(i+0), shadow_png_hover); 
												$('.layer_img_shadow_'+(i-1), that).show();
												if(old_active_id != null) break;
											}
										}
										// Для только что выбранного
										changeImage(that, '.layer_img_'+layer_id, options.layers[layer_id].src);
										changeImage(that, '.layer_img_shadow_'+(layer_id+0), shadow_png);
										$('.layer_img_shadow_'+(layer_id-1), that).hide();
										showWindow(that, options);
										return false;
			 						})
			 						// Блочим клики
			 						.livequery('click', function(){return false;})
			 						.livequery('mouseout', function(){
										var layer_id = $(this).attr('id').split('_')[4];
										$('#'+id+'_map_layer_'+layer_id+', #'+id+'_layer_name_'+layer_id).removeClass(model+'_area_over');	
										//$('.'+model+'_mini_window_'+layer_id).show();
				 						//$(this).removeClass(model+'_area_over');
				 					});
				 						 							
			 						// При выходе из блока модели
			 						$('#'+id, that).livequery('mouseout', function(){
				 							setTimeout(function(){
					 							if(!$('.'+model+'_map_layer.'+model+'_area_over', that).length && options.active_id != null){
						 							//alert(1)	 
					 								// unbind the mouseover and mouseout events 
					 						        //$('.'+model+'_map_layer', that).unbind('mouseover').unbind('mouseout');						            
			 						            	options.active_id = null;
			 						            	$('.'+model+'_window', that).hide();	 						            	
			 						            	
			 						    			for(var i=0; i<options.layers.length; i++)
			 						    			{
			 						    				changeImage(that, '.layer_img_'+i, options.layers[i].src);
			 						    				changeImage(that, '.layer_img_shadow_'+(i+0), shadow_png);
			 						    				//$('.layer_img_shadow_'+(i-1), that).show();	 						    				
			 						    			}						
						 						}
				 							}, 50);
									})
									.livequery('mouseout', function(){
										if(options.active_id == null){
				 										 							
										}
										//else alert(1)
									});
								}
 							}
 							// для ie <= 6
 							else{
 								var visual = $('.'+model+'_visual', that);
 								$('<div class="'+model+'_for_ie6">Внимание! Интерактивная модель не работает в браузерах IE ниже 7 версии.</div>')
 								.css({width:options.imgW*1+options.block_paddingLeft})
 								.appendTo(visual);
 							}
	 						var cal =$('#' + $(this).data(model_id));
	 						cal.data(model, options); 							
						}
					}
				});
				 	 				
			}
			/*
			*	Показ блока
			*/
			,showModel: function(){
				return this.each( function () {
					$(this).show();
				});
			}
			/*
			*	Скрывание блока
			*/
			,hideMode: function(){
				return this.each( function () {
					$(this).hide();
				});
			}
			/*
			*	Рендер по новым слоям
			*/
			,setLayers: function(layers){
				var that = $(this);
				var id = that.data(model_id);
				var cal =$('#' + that.data(model_id));
				var options = cal.data(model);
				options.layers = layers;
				options.count = options.layers.length; 			
				cal.data(model, options);		
				renderScheme(that, options, id);
			}
		}
	}();
	$.fn.extend({
		model3D: model3D.init
		,model3DShow: model3D.showModel
		,model3DHide: model3D.hideMode
		,model3DSetLayers: model3D.setLayers
	});
	
})(jQuery);
