function CoopepPicker (sJsonUrl, iPackSize, sImageUrlFormat){

	this.jsonUrl = sJsonUrl;
	this.packSize = iPackSize;
	this.hasPhotos = false;
	this.hasSets = false;
	this.hasTags = false;
	this.isBot = false;
	this.scrollAlertUnit = 2000;
	this.nextScrollAlert = -2000;
	this.currentScrollPage = 0;
	this.lastActiveDuplicatorId = "";
	this.imageUrlFormat = sImageUrlFormat;
	this.originalTag='';

	this.setup = function(){
		//got any piccies / tags / sets?
		if (get("hidHasPhotos").value == 1){this.hasPhotos = 1;}
		if (get("hidHasSets").value == 1){this.hasSets = 1;}
		if (get("hidHasTags").value == 1){this.hasTags = 1;}
		if (get("hidIsBot").value == 1){this.isBot = 1;}

		//set defaults
		if(this.isBot == false){
			this.changeTab("photostream");
		}else{
			this.changeTab("comp");
		}

		//make any existing images draggable
		var aPicked = document.getElementsByClassName('picked');
			for(i=0;i<aPicked.length;i++) {
				oDrag = new Draggable(aPicked[i].id,{revert:true});
				oDrag.options.change = function (value){
			        get("divDeletePicked").className="hover";
			    }
			}

		//drop area
		Droppables.add("divPickedImages",
	  	   {
	  	       hoverclass:'imagehover',
	  	       onDrop: function(element, dropon, event){
	  	           CoolPicker.onImageDropped(element, dropon, event);
	  	       }
	  	   });

		//delete area
		Droppables.add("divDeletePicked",
	  	   {
	  	       hoverclass:'hover',
	  	       onDrop: function(element, dropon, event){
	  	           CoolPicker.onImageDelete(element, dropon, event);
	  	       }
	  	   });

		//show count message
		this.showCounter();
		if(this.getImageCount() ==0){
			this.showDragHint();
		}

		//Remove validator elements
		get("ulPickedImages").removeChild(get("liValidate"));


		//Scriptaculous autocomplete ? ? ? ?
		if (this.hasTags == true){
			var oAjaxAC = new Ajax.Autocompleter("txtTag", "div_autocomplete_choices", this.jsonUrl + "?search_type=taglist", {afterUpdateElement: this.tagSelected, frequency:0.1});
		}

		this.originalTag = get('txtTag').value;

	}

	this.resetFilmstrip = function (){
		get("ulBrowserImages").innerHTML = "";
		get("pLoadingInfo").style.display ="block";
		this.currentScrollPage = 0;
		this.resetScroll();
	}

	this.loadingEnd = function (){
		get("pLoadingInfo").style.display ="none";
	}

	this.changeTab = function(sSelectedTab){

		//reset selected
		aTabs = document.getElementsByClassName('browsertab');
		for(i=0;i<aTabs.length;i++) {
			aTabs[i].className = "browsertab";
		}

		//reset filters and tools
		get("ddlSetFilter").style.display="none";
		get("txtTag").style.display="none";

		get("lbl_autocomplete").style.display="none";
		//get("pCompHint").style.display="none";

		var oRandomFill = get("aRandomFill");
		var oRandom10 = get("aRandom10");
		oRandomFill.className = "";
		oRandomFill.href="javascript:CoolPicker.fillRandom()"
		oRandom10.className = "";
		oRandom10.href="javascript:CoolPicker.random(10)"
		//get the piccies
		switch (sSelectedTab){
			case "photostream":

				sSelectedTab ="aTab_PhotoStream";
				if (this.hasPhotos == true){
					this.setImages('photostream', '', true);
					this.setPhotoBrowserWarning("");
				}else{
					this.setPhotoBrowserWarning('抱歉, 您似乎没有任何相片.');
					this.clearImageBrowser();
				}
				this.mode = "photostream";
			break;
			case "set":
				oFilterDropdown = get("ddlSetFilter");

				get("txtTag").style.display="none";
				get("lbl_autocomplete").style.display="none";

				sSelectedTab ="aTab_Set";
				if (this.hasSets == true){
					this.setImages('set', oFilterDropdown.value, true);
					this.setPhotoBrowserWarning("");
				}else{
					this.setPhotoBrowserWarning('抱歉, 您似乎没有任何相集');
					this.clearImageBrowser();
				}
				this.mode = "set";
				if (this.hasSets == true){
					oFilterDropdown.style.display="inline";
				}else{
					oRandomFill.className += " disabled";
					oRandomFill.href=""
					oRandom10.className += " disabled";
					oRandom10.href="";
				}
			break;

			case "tag":

				get("txtTag").value = this.originalTag;

				oDivAutoCompleteChoices = get("div_autocomplete_choices");
				oLblAutoComplete = get("lbl_autocomplete");
				oInputAutoComplete = get('txtTag');

				oInputAutoComplete.style.display='inline';
				oLblAutoComplete.style.display='inline';

				CoolPicker.setImages('tag', get('txtTag').value, true);
				oInputAutoComplete.select();
				oInputAutoComplete.focus();

				//reset suggestions
				oDivAutoCompleteChoices.innerHTML = "";
				sSelectedTab ="aTab_Tag";

				if (this.hasTags == true){
					this.setPhotoBrowserWarning("");
				}else{
					this.setPhotoBrowserWarning('抱歉, 您似乎没有任何标签');
					this.clearImageBrowser();
				}

				this.mode = "tag";

				if (this.hasTags == true) {

					//style and select
					oDivAutoCompleteChoices.style.display = 'inline';
					oDivAutoCompleteChoices.style.top = 24 + 'px';
					oDivAutoCompleteChoices.style.right = 1 + 'px';
					//for Safari and Opera to stop them hiding suggestions behind save button
					oDivAutoCompleteChoices.style.zIndex = 3;
					get('ulBrowserImages').style.zIndex = 1;

					oInputAutoComplete.select();
					oInputAutoComplete.focus();

				}else{
					oRandomFill.className += " disabled";
					oRandomFill.href=""
					oRandom10.className += " disabled";
					oRandom10.href="";
				}

			break;

			case "comp":
					sSelectedTab ="aTab_Comp";
					this.setImages('comp', '', true);
					this.setPhotoBrowserWarning("");
				//	get("pCompHint").style.display = "block";
					this.mode = "comp";

					var selectedgallery = get("hidSelectedGallery");
					selectedgallery.value = "true";
			break;
		}

		//Set selected
		get(sSelectedTab).className = "browsertab selected";
	}

	this.tagSelected  = function () {
		CoolPicker.setImages('tag', get('txtTag').value, true);
	}


	this.setImages = function (sSearchType, sSearchArgument, bReset){

		if (bReset == true){
			this.resetFilmstrip();
		}

		//increase the scroll page
		this.currentScrollPage +=1;

		var sPost = "";
		sPost = "search_type=" + sSearchType + "&search_argument=" + sSearchArgument + "&search_count=" + 100 + "&search_page=" + (this.currentScrollPage);
		var oAjax = new Ajax.Request(this.jsonUrl, {method: 'post',  postBody: sPost,  onComplete: this.addImagesCallback});

	}

	this.addImagesCallback = function (originalRequest){

		//error checking
		if (originalRequest.responseText == "null"){
			oMooDebug = new MooDebug();
			oMooDebug.error("Empty JSON response when trying to get images");
		}
			oMooDebug = new MooDebug();
			oFilmStrip = get("ulBrowserImages");

		//get the response and convert to js
		var oResponse = originalRequest.responseText;

//		document.write(oResponse);

		var oPhotos = eval('('+oResponse+')');

		//loop through images and add to the list
		var aImageId = new Array();
		sImageHtml = "";

		for(i=0;i<oPhotos.length;i++) {

			oImage = document.createElement('li');
			oImage.innerHTML = '<img id="imgBrowser_' + oPhotos[i].id +  '" class="browserimage" src="' + oPhotos[i].url +  '" alt="' + oPhotos[i].id + '"  title="'  + oPhotos[i].title + '" />';
			oFilmStrip.appendChild(oImage);

			new SubsDraggable('imgBrowser_' + oPhotos[i].id, {dragelement:CoolPicker.getDragElement});
		}

		get("pLoadingInfo").style.display ="none";

		// what to do if no photos are returned?
		if(oPhotos.length < 1 && oFilmStrip.childNodes.length == 0){
			var oWarning = get("pNoPhotos");
			// TODO
			// This is really a non-instantiated version of this.setPhotoBrowserWarning(),
			// and possibly not the best way to do things, but it's a temporary solution
			// until fotolog starts using YEARS instead of TAGS, or we can work out another way
			// to test and warn for an enpty image array.
			//
			// we don't want to override any warnings that have already been set
			if (oWarning.childNodes[0].innerHTML == "") {
				oWarning.innerHTML = '<span class="infobox">抱歉, 检索你的图片发生了错误。请再试一次.</span>';
				oWarning.style.display="block";
			}
		}else{
			var oWarning = get("pNoPhotos");
			oWarning.childNodes[0].innerHTML = "";
			oWarning.style.display="none";
		}

	}

	this.clearImageBrowser = function(){
		get("ulBrowserImages").innerHTML = "";
		get("pLoadingInfo").style.display ="none";
	}

	this.scroll = function(sDirection){

		var iShift = 549;

		if (this.canScroll(sDirection, iShift) == true || sDirection == "right"){
			var oImageHolder = get("ulBrowserImages");
			var bScrollAlert = false;
			if (sDirection == "right"){
				new Effect.MoveBy('ulBrowserImages', 0, parseInt("-" + iShift));
				if (parseInt(get('ulBrowserImages').style.left) <= this.nextScrollAlert){
					bScrollAlert = true;
				}
			}else{
	 			new Effect.MoveBy('ulBrowserImages', 0, iShift);
			}
			if (bScrollAlert == true){
				setTimeout("CoolPicker.topUpPhotos();", 1000);
			}
		}

	}

	this.resetScroll = function(){
		get("ulBrowserImages").style.left = 0;
	}

	this.canScroll =  function (sDirection, iProposed){

		var oImageHolder = get("ulBrowserImages");
		var oImageScroller = get("divBrowserScroller");
		var bCanScroll = true;

		if (sDirection == "left" && (parseInt(oImageHolder.style.left) + iProposed) <=0){
			bCanScroll = true;
		}else{
			bCanScroll = false;
		}

		if (sDirection == "right"){
			var iScrollerWidth = oImageHolder.offsetWidth;
			var iStripWidth = oImageHolder.offsetWidth;
			var iStripPosition = parseInt(oImageHolder.style.left);

			if ((iStripPosition - iProposed) < (iStripWidth - iScrollerWidth)){
				bCanScroll = false;
			}else{
				bCanScroll = true;
			}
		}
		return bCanScroll;

	}

	this.topUpPhotos = function(){
		//only do this for photostream and tags
		if (this.mode == "photostream" || this.mode == "comp"){
			this.setImages(this.mode);
		}
		if (this.mode == "tag"){
			this.setImages(this.mode, get("txtTag").value);
		}
		this.nextScrollAlert = this.nextScrollAlert - this.scrollAlertUnit;

	}

	this.getDragElement = function(element) {
		var oElement = element.cloneNode(true);
	 	oElement.id = 'sub'+element.id;
	 	oElement.style.position = 'relative';
		oElement.style.zIndex = 99;
		oElement.style.cursor = "move";
	 	document.body.appendChild(oElement);
	 	return oElement;
	}

	this.onImageDropped = function(oImage, oDestination, oEvent) {

			var sImageSrc = oImage.src;
			oImage.display= "none";
			if (oImage.className=="browserimage"){
				if (this.getImageCount() < this.packSize){
					this.pickImage(sImageSrc , true);
				}else{
					oImage.style.display="none";
					alert("你已准备好了足够的图片，点击下一步操作图片");
				}
			}else if(oImage.className == "picked"){
				get("divDeletePicked").className="";
			}
	}

	this.imageHasBeenPicked = function (sUrl, bFlash){

		//Get the ID
        var sImageId = this.extractImageId(sUrl);
		var bExists = false;

		if (document.getElementById('hidPicked_' + sImageId)){
			bExists = true;
			if (bFlash == true){
				 Effect.Pulsate('img' + sImageId, {duration: 2, from:0.5});
			}
		}

		return bExists;
	}

	this.onImageDelete = function(oImage, oDestination, oEvent) {

		if (oImage.className == "picked"){
			//funky image fade thingy
			Effect.Puff(oImage.id, {duration:0.4});

			var aSplit = oImage.id.split("_");
			var iDuplicateNumber = aSplit[1];

			this.deleteImage(oImage.src, iDuplicateNumber);

			this.showMessage("Photo removed", true);
		}
	}

	this.clearAllImages = function(){

		get("fstPickedImages").innerHTML = "";
		get('ulPickedImages').innerHTML = "";

		this.showCounter();
		this.showDragHint();
	}

	this.deleteImages = function(iCount, bConfirm){

		var oImages = document.getElementsByClassName('picked');
		var iImageCount = oImages.length;
		for((i=iImageCount - 1);i>=((iImageCount) - iCount) ;i--) {
			this.deleteImage(oImages[i].src);
		}

	}

	this.deleteImage = function(sUrl){

		//remove hidden input
		var sImageId = this.extractImageId(sUrl);
		var oPickedInput = get("hidPicked_" + sImageId);

		get("fstPickedImages").removeChild(oPickedInput);

		var oListItem = get("li" + sImageId);
		get("ulPickedImages").removeChild(oListItem);

		//if no images left, reshow the drag hint
		if (this.getImageCount() == 0 ){
			this.showDragHint();
		}
	}

	this.pickImage = function(sImageUrl, bShowMessages){

		if (this.imageHasBeenPicked(sImageUrl, bShowMessages) == false){

			//hide the intro message
			get('pPickedHint').style.display = "none";

			//Get the ID
	        sImageId = this.extractImageId(sImageUrl);

			//Create hidden element
			var iCount = 1;
			var oPickedImageFieldset = get("fstPickedImages");
			var sInput = '<input type="hidden" id="hidPicked_' + sImageId + '" name="hidPicked_' + sImageId + '" class="pickedinfo" value="' + sImageUrl + '" />';
			oPickedImageFieldset.innerHTML += sInput;

			//create and add the image
			var oPickedimages = document.getElementById('ulPickedImages');
			var oPickedImage = document.createElement('li');
			oPickedImage.id = "li" + sImageId;

			oPickedImage.innerHTML = '<img id="img' + sImageId + '" class="picked" src="' +  sImageUrl + '" />';

			oPickedimages.appendChild(oPickedImage);

			//make draggable
			oDrag = new Draggable( 'img' + sImageId, {revert:true});
			oDrag.options.change = function (value){
		        get("divDeletePicked").className="hover";
		    }
			if (bShowMessages == true){
				this.showMessage("添加1张图片!", true);
			}
		}else{
			if(bShowMessages == true){
				this.showMessage("已经添加", true,false, "#f03b1f");
			}
		}
	}

	this.fillRandom = function(){
		if (this.getImageCount() != this.packSize){
			this.pickBulkImages("random", this.packSize - this.getImageCount());
		}else{
			alert("您已经设计好了图片. 点击下一步开始做卡片");
		}
	}

	this.random = function (iCount){
		if (this.getImageCount() + iCount <= this.packSize){
			this.pickBulkImages("random", 10);
		}else if (this.getImageCount() == this.packSize){
			alert("您已经设计好了图片. 点击下一步开始做卡片");
		}else{
			alert("抱歉, 那里足够位置存放" + iCount + " 相片 ");
		}
	}

	this.pickBulkImages = function (sType, iCount){

		setCursor("wait");
		this.showMessage("检索图片", false);

		var bProceed = false;
		var iExistingPickedCount = this.getImageCount();

		//clear photos
		if ((iCount + iExistingPickedCount) > this.packSize){
			CoolPicker.deleteImages(iCount - (this.packSize - iExistingPickedCount), false);
		}

		//get new ones
		var sSearchType = this.mode + sType;
		var sPost = "search_type=" + sSearchType + "&search_argument=";
		if (this.mode =="tag"){
			sPost += get("txtTag").value;
		}

		if (this.mode =="set"){
			sPost += get("ddlSetFilter").value;
		}

		sPost += "&search_count=" + iCount;
		sPost += "&exclude_ids=" + this.getPickedCsv();

		var oAjax = new Ajax.Request(this.jsonUrl, {method: 'post',  postBody: sPost,  onComplete: this.pickBulkImagesCallback});

	}

	this.pickBulkImagesCallback = function(oResponse){

		//add photos
		var oPhotos = eval('('+oResponse.responseText+')');

		iCurrentCount = CoolPicker.getImageCount();

		for(i=0;i<oPhotos.length;i++) {
			iCurrentCount += 1;
			if (iCurrentCount <= CoolPicker.packSize){
				try{
					CoolPicker.pickImage(oPhotos[i].url);
				}catch(e){
					oMooDebug = new MooDebug();
					oMooDebug.info(oPhotos[i] + '' +  i);
				}
			}
		}

		setCursor("default");
		CoolPicker.showCounter();

	}

	this.extractImageId = function(sUrl){
		var sId = "";
		if(CoolPicker.imageUrlFormat == "flickr"){
			var aSplit = sUrl.split("_");
			sId = aSplit[0];
			aSplit = sId.split("/");
			sId = aSplit[aSplit.length -1];
		}else if(CoolPicker.imageUrlFormat == "fotolog"){
			var aSplit = sUrl.split("&");
			sId = aSplit[aSplit.length -1];
			sId = sId.replace("id=", "")
		}else if(CoolPicker.imageUrlFormat == "moo"){
			var aSplit = sUrl.split("/");
			sId = aSplit[aSplit.length -1];
			sId = sId.replace(".jpeg", "")
		}else if(CoolPicker.imageUrlFormat == "bebo"){
			var aSplit = sUrl.split("/");
			sId = aSplit[aSplit.length -1];
			sId = sId.replace(/(s|o|m|l|o).(jpeg|jpg|png|bmp|gif)/g, "");
			sId = sId.replace(/(.*)a/g, "");
			sId = sId.replace(/b(.*)/g, "");
		}
		return sId;

	}

	this.getImageCount = function(){
		var iCount  = 0;
		var oImages = document.getElementsByClassName('picked');
		iCount = oImages.length;
		return iCount;
	}

	this.showDragHint = function (){

		get('pPickedHint').style.display="none"
		var o = new Effect.Appear(get('pPickedHint'), {duration: 0.5});

	}

	this.hideDragHint = function (){
		get('pPickedHint').style.display="none";
	}

	this.showCounter = function(){

		var sMessage = " 每张图片 {y}份 {x}";
		var iImageCount = this.getImageCount();
		var iMultiples = Math.floor(this.packSize / iImageCount);
		var iRemainder = this.packSize - iMultiples * iImageCount;
		if (iImageCount == 0){
			sMessage = "选择一些图片"
		}else if (iRemainder == 0){
			sMessage = sMessage.replace("{y}", iMultiples).replace("{x}","");
		}else{
			sMessage = sMessage.replace("{y}", iMultiples).replace("{x}","(大约)");
		}
		this.showMessage(sMessage, false);

	}

	this.showMessage = function (sMessage, bRevertToCounter, bNoFade, sBackgroundColour){
		var oMessege = get("liPickerInfo");
		if (sBackgroundColour == undefined){
				oMessege.style.backgroundColor = "";
				oMessege.style.color = "";
		}else{
				oMessege.style.backgroundColor = sBackgroundColour;
				oMessege.style.color = "white";
		}

		if(bNoFade == false){
			get("sPickerInfo").style.display = "none";
			Effect.Appear('sPickerInfo', {duration: 0.2 });
		}
		get("sPickerInfo").innerHTML = sMessage;

		if(bRevertToCounter == true){
			setTimeout('CoolPicker.showCounter()', 2000);
		}

	}

	this.setPhotoBrowserWarning  = function (sText){
		var oWarning = get("pNoPhotos");
		if (sText!=""){
			oWarning.innerHTML = '<span class="infobox">' + sText + "</span>";
			oWarning.style.display="block";
		}else{
			oWarning.childNodes[0].innerHTML = "";
			oWarning.style.display="none";
		}
	}

	this.getPickedCsv = function(){

		var sCsv = "";

		var aPicked = document.getElementsByClassName('pickedinfo');
		for(i=0;i<aPicked.length;i++) {
			aSplit = aPicked[i].id.split("_")
			sCsv += aSplit[1];
			if (1 < aPicked.length -1){
				sCsv +=",";
			}
		}
		return sCsv;
	}

	this.save = function(){
		if (this.getImageCount() == 0){
		    alert("抱歉, 你必须选择一张图片 ");
		}else{
			postBackForm("frmStudio");
		}
	}

	//call setup
	if (!document.getElementById('hidDontLoad')){
		this.setup();
	}

}
