define(['jquery', 'bootstrap', 'webupload'], function ($, undefined, WebUploader) {
	var Upload = {
		config: {
			image: {
				title: 'Images',
				extensions: 'gif,jpg,jpeg,bmp,png',
				mimeTypes: 'image/*'
			},
			file: {
				title: 'Files',
				extensions: '*',
				mimeTypes: '*'
			},
			upList: [],
		},
		index: function(){
			var query = sent.parseUrl(window.location.href);
			$wrap = $('#uploader'),
			// 图片容器
			$queue = $('<ul class="filelist"></ul>')
				.appendTo( $wrap.find('.queueList') ),
			// 状态栏，包括进度和控制按钮
			$statusBar = $wrap.find('.statusBar'),
			// 文件总体选择信息。
			$info = $statusBar.find('.info'),
			// 上传按钮
			$upload = $wrap.find('.uploadBtn'),
			// 没选择文件之前的内容。
			$placeHolder = $wrap.find('.placeholder'),
			// 总体进度条
			$progress = $statusBar.find('.progress').hide(),
			// 添加的文件数量
			fileCount = 0,
			// 添加的文件总大小
			fileSize = 0,
			// 优化retina, 在retina下这个值是2
			ratio = window.devicePixelRatio || 1,
			// 缩略图大小
			thumbnailWidth = 110 * ratio,
			thumbnailHeight = 110 * ratio,
			// 可能有pedding, ready, uploading, confirm, done.
			state = 'pedding',
			// 所有文件的进度信息，key为file id
			percentages = {},
			supportTransition = (function(){
				var s = document.createElement('p').style,
					r = 'transition' in s ||
						  'WebkitTransition' in s ||
						  'MozTransition' in s ||
						  'msTransition' in s ||
						  'OTransition' in s;
				s = null;
				return r;
			})(),
			// WebUploader实例
			uploader;

			if ( !WebUploader.Uploader.support() ) {
				alert( 'Web Uploader 不支持您的浏览器！如果你使用的是IE浏览器，请尝试升级 flash 播放器');
				throw new Error( 'WebUploader does not support the browser you are using.' );
			}
			// 实例化
			uploader = WebUploader.create({
				pick: {
					id: '#filePicker',
					label: '点击选择'+(query.type == 'image' ? '图片' : '文件')
				},
				dnd: '#uploader .queueList',
				paste: document.body,
				accept: Upload.config[query.type],
				// swf文件路径
				// swf: baseRoot + 'plugins/webuploader/Uploader.swf',
				disableGlobalDnd: true,
				chunked: true,
				// server: 'http://webuploader.duapp.com/server/fileupload.php',
				server: '/'+Config.module+'/upload/upload',
				fileNumLimit: 300,
				fileSizeLimit: 5 * 1024 * 1024,    // 200 M
				fileSingleSizeLimit: 1 * 1024 * 1024    // 50 M
			});

			// 添加“添加文件”的按钮，
			uploader.addButton({
				id: '#filePicker2',
				label: '继续添加'
			});

			uploader.onUploadProgress = function( file, percentage ) {
				var $li = $('#'+file.id),
					$percent = $li.find('.progress span');

				$percent.css( 'width', percentage * 100 + '%' );
				percentages[ file.id ][ 1 ] = percentage;
				Upload.updateTotalProgress();
			};

			uploader.onFileQueued = function( file ) {
				fileCount++;
				fileSize += file.size;

				if ( fileCount === 1 ) {
					$placeHolder.addClass( 'element-invisible' );
					$statusBar.show();
				}
				Upload.addFile( file );
				Upload.setState( 'ready' );
				Upload.updateTotalProgress();
			};

			uploader.onFileDequeued = function( file ) {
				fileCount--;
				fileSize -= file.size;

				if ( !fileCount ) {
					Upload.setState( 'pedding' );
				}

				Upload.removeFile( file );
				Upload.updateTotalProgress();

			};

			uploader.on( 'all', function( type, file, response ) {
				var stats;
				switch( type ) {
					case 'uploadFinished':
						Upload.setState( 'confirm' );
						Upload.uploadFinished();
						break;
					case 'uploadSuccess':
						Upload.uploadSuccess(response, file);
						break;
					case 'startUpload':
						Upload.setState( 'uploading' );
						break;

					case 'stopUpload':
						Upload.setState( 'paused' );
						break;

				}
			});

			uploader.onError = function( code ) {
				sent.msg( 'Eroor: ' + code, 'error' );
			};

			$upload.on('click', function() {
				if ( $(this).hasClass( 'disabled' ) ) {
					return false;
				}
				if ( state === 'ready' ) {
					uploader.upload();
				} else if ( state === 'paused' ) {
					uploader.upload();
				} else if ( state === 'uploading' ) {
					uploader.stop();
				}
			});

			$info.on( 'click', '.retry', function() {
				uploader.retry();
			} );

			$info.on( 'click', '.ignore', function() {
				alert( 'todo' );
			} );

			$upload.addClass( 'state-' + state );
			Upload.updateTotalProgress();
		},
		// 当有文件添加进来时执行，负责view的创建
		addFile: function ( file ) {
			var $li = $( '<li id="' + file.id + '">' +
					'<p class="title">' + file.name + '</p>' +
					'<p class="imgWrap"></p>'+
					'<p class="progress"><span></span></p>' +
					'</li>' ),

				$btns = $('<div class="file-panel">' +
					'<span class="cancel">删除</span>' +
					'<span class="rotateRight">向右旋转</span>' +
					'<span class="rotateLeft">向左旋转</span></div>').appendTo( $li ),
				$prgress = $li.find('p.progress span'),
				$wrap = $li.find( 'p.imgWrap' ),
				$info = $('<p class="error"></p>'),

				showError = function( code ) {
					switch( code ) {
						case 'exceed_size':
							text = '文件大小超出';
							break;

						case 'interrupt':
							text = '上传暂停';
							break;

						default:
							text = '上传失败，请重试';
							break;
					}

					$info.text( text ).appendTo( $li );
				};

			if ( file.getStatus() === 'invalid' ) {
				showError( file.statusText );
			} else {
				// @todo lazyload
				$wrap.text( '预览中' );
				uploader.makeThumb( file, function( error, src ) {
					if ( error ) {
						$wrap.text( '不能预览' );
						return;
					}

					var img = $('<img src="'+src+'">');
					$wrap.empty().append( img );
				}, thumbnailWidth, thumbnailHeight );

				percentages[ file.id ] = [ file.size, 0 ];
				file.rotation = 0;
			}

			file.on('statuschange', function( cur, prev ) {
				if ( prev === 'progress' ) {
					$prgress.hide().width(0);
				} else if ( prev === 'queued' ) {
					$li.off( 'mouseenter mouseleave' );
					$btns.remove();
				}

				// 成功
				if ( cur === 'error' || cur === 'invalid' ) {
					console.log( file.statusText );
					showError( file.statusText );
					percentages[ file.id ][ 1 ] = 1;
				} else if ( cur === 'interrupt' ) {
					showError( 'interrupt' );
				} else if ( cur === 'queued' ) {
					percentages[ file.id ][ 1 ] = 0;
				} else if ( cur === 'progress' ) {
					$info.remove();
					$prgress.css('display', 'block');
				} else if ( cur === 'complete' ) {
					$li.append( '<span class="success"></span>' );
				}

				$li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
			});

			$li.on( 'mouseenter', function() {
				$btns.stop().animate({height: 30});
			});

			$li.on( 'mouseleave', function() {
				$btns.stop().animate({height: 0});
			});

			$btns.on( 'click', 'span', function() {
				var index = $(this).index(),
					deg;

				switch ( index ) {
					case 0:
						uploader.removeFile( file );
						return;

					case 1:
						file.rotation += 90;
						break;

					case 2:
						file.rotation -= 90;
						break;
				}

				if ( supportTransition ) {
					deg = 'rotate(' + file.rotation + 'deg)';
					$wrap.css({
						'-webkit-transform': deg,
						'-mos-transform': deg,
						'-o-transform': deg,
						'transform': deg
					});
				} else {
					$wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
				}
			});

			$li.appendTo( $queue );
		},
		// 负责view的销毁
		removeFile: function ( file ) {
			var $li = $('#'+file.id);

			delete percentages[ file.id ];
			Upload.updateTotalProgress();
			$li.off().find('.file-panel').off().end().remove();
		},
		updateTotalProgress: function() {
			var loaded = 0,
				total = 0,
				spans = $progress.children(),
				percent;

			$.each( percentages, function( k, v ) {
				total += v[ 0 ];
				loaded += v[ 0 ] * v[ 1 ];
			} );

			percent = total ? loaded / total : 0;

			spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
			spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
			Upload.updateStatus();
		},
		updateStatus: function () {
			var text = '', stats;

			if ( state === 'ready' ) {
				text = '选中' + fileCount + '张图片，共' +
						WebUploader.formatSize( fileSize ) + '。';
			} else if ( state === 'confirm' ) {
				stats = uploader.getStats();
				if ( stats.uploadFailNum ) {
					text = '已成功上传' + stats.successNum+ '张照片至XX相册，'+
						stats.uploadFailNum + '张照片上传失败，<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>'
				}

			} else {
				stats = uploader.getStats();
				text = '共' + fileCount + '张（' +
						WebUploader.formatSize( fileSize )  +
						'），已上传' + stats.successNum + '张';

				if ( stats.uploadFailNum ) {
					text += '，失败' + stats.uploadFailNum + '张';
				}
			}

			$info.html( text );
		},
		setState: function ( val ) {
			var file, stats;

			if ( val === state ) {
				return;
			}

			$upload.removeClass( 'state-' + state );
			$upload.addClass( 'state-' + val );
			state = val;

			switch ( state ) {
				case 'pedding':
					$placeHolder.removeClass( 'element-invisible' );
					$queue.parent().removeClass('filled');
					$queue.hide();
					$statusBar.addClass( 'element-invisible' );
					uploader.refresh();
					break;

				case 'ready':
					$placeHolder.addClass( 'element-invisible' );
					$( '#filePicker2' ).removeClass( 'element-invisible');
					$queue.parent().addClass('filled');
					$queue.show();
					$statusBar.removeClass('element-invisible');
					uploader.refresh();
					break;

				case 'uploading':
					$( '#filePicker2' ).addClass( 'element-invisible' );
					$progress.show();
					$upload.text( '暂停上传' );
					break;

				case 'paused':
					$progress.show();
					$upload.text( '继续上传' );
					break;

				case 'confirm':
					$progress.hide();
					$upload.text( '开始上传' ).addClass( 'disabled' );

					stats = uploader.getStats();
					if ( stats.successNum && !stats.uploadFailNum ) {
						Upload.setState( 'finish' );
						return;
					}
					break;
				case 'finish':
					stats = uploader.getStats();
					if ( stats.successNum ) {
						sent.msg( '上传成功', 'success' );
					} else {
						// 没有成功的图片，重设
						state = 'done';
						location.reload();
					}
					break;
			}

			Upload.updateStatus();
		},
		uploadSuccess: function(res, file){
			if (res.code == 1) {
				Upload.config.upList.push(res.info);
			}
		},
		uploadFinished: function(){
			var query = sent.parseUrl(window.location.href);
			if(Upload.config.upList.length > 0){
				if(query.limit == 1 && Upload.config.upList.length > 1){
					sent.msg('请单选图片或文件', 'error');
					return false;
				}
				parent.Form.api.setFile(Upload.config.upList, query);
			}else{
				sent.msg('未选择数据！', 'error')
			}
		},
		server: function(){
			var query = sent.parseUrl(window.location.href);
			if($('.img-list .item .thumb, .file-list .item .attach').length > 0){
				$('.img-list .item .thumb, .file-list .item .attach').on('click', function(){
					if($(this).hasClass('selected')){
						Upload.config.upList = Upload.config.upList.filter(item => !sent.utils.isObjEqual(item, $(this).data()));
						$(this).removeClass('selected');
					}else{
						Upload.config.upList.push($(this).data());
						$(this).addClass('selected');
					}
				})
			}
			$('button.btn-select').click(function(){
				if(Upload.config.upList.length > 0){
					if(query.limit == 1 && Upload.config.upList.length > 1){
						sent.msg('请单选图片或文件', 'error');
						return false;
					}
					parent.Form.api.setFile(Upload.config.upList, query);
				}else{
					sent.msg('未选择数据！', 'error')
				}
			})
		}
	}

	return Upload;
})