function CoopepCardBack (sFormId, bHasMeta, bHasFonts, bHasIcons, bHasBackgrounds, bHasIconBackgrounds, bHasDesignHasPartnerLogo){

	//properties
	m_sFormId = sFormId;
	m_hasMeta = bHasMeta;
	m_has_Fonts = bHasFonts;
	m_has_icons = bHasIcons;
	m_has_Backgrounds = bHasBackgrounds;
	m_hasIconBackgrounds = bHasIconBackgrounds;
	m_HasDesignHasPartnerLogo = bHasDesignHasPartnerLogo;

	//sync free text line
	this.syncLine = function(sLine){

	  var oInput = get('txtLine' + sLine);
	  var oPreview = get('pLine' + sLine).childNodes[0];

	  sText = oInput.value;

	//Change all spaces to &nbsp;
	while (sText.indexOf(' ') >= 0)
	{
		sText = sText.replace(' ', '&nbsp;');
	}

	sText = sText.replace("<", "&#60;").replace(">", "&#62;").replace("/", "&#47;");

	  //Store value
	  get('hidLine' + sLine).value = sText;

	 //Show onpreview (convert spaces)
	  oPreview.innerHTML  = sText;

		//Workout how much room is left
		var iTextAvaliableWidth = oPreview.parentNode.offsetWidth;
		var iTextPercentRemaining = (iTextAvaliableWidth - oPreview.offsetWidth) /2;
		var iInputWidth = oInput.offsetWidth;
		var iProgressPosition  = parseInt((iInputWidth / 100) * iTextPercentRemaining);
		oInput.style.backgroundPosition = -iProgressPosition + 'px 0px';

		if (oPreview.innerHTML.length <25 || (iTextPercentRemaining > 1 && oPreview.offsetHeight < 20)){
			oInput.className = oInput.className.replace(' fullup', '');
		}else{
			oInput.className += ' fullup';
		}
	}

	//sync all free text lines
	this.syncAllLines = function(){
		for (i=1; i<=6; i++) {
			if (m_hasMeta == false){
				this.syncLine(i);
			}else{
				if (get("ddlMetaToggle" + i).value =="freetext"){
					this.syncLine(i);
				}else{
					this.setMetaFullName(i);
				}
			}
		}
	}

	//bold
	this.emboldenLine = function(sLine, oCheckbox) {

		var oPreview = get('pLine' + sLine)
		 if (oCheckbox.checked == true){
		        oPreview.style.fontWeight = "bold";
				if (m_hasMeta == true){
					if (get("ddlMetaToggle" + sLine).value=="freetext"){
						this.syncLine(sLine);
					}
				}else{
					this.syncLine(sLine);
				}
		    }else{
		        oPreview.style.fontWeight = "";
		 }
	}

	//toggle partner
	this.togglePartnerLogo = function(){
		var oChecked = get('chkPartnerLogo');
		if (oChecked.checked == true){
	        get('imgPartnerLogo').style.display = 'block';
			get('imgAvatarBack').className="partner";
	    }else{
	        get('imgPartnerLogo').style.display = 'none';
			get('imgAvatarBack').className="none";
		}

		//Check for background change
		this.refreshBackground();
	}

	this.changeFont = function(sFont){
		get("divPreview").className = sFont;
        aPreviewtext = document.getElementsByClassName('previewline');
        for (i=0; i < aPreviewtext.length; i++) {
          aPreviewtext[i].style.fontFamily = sFont;
        }
		this.syncAllLines();
	}

 	this.changeBackground = function (sBackground){

		//set selected in background picker
		var aIcons = document.getElementsByClassName('backgrounditem');
		for (var i=0; i < aIcons.length; i++) {
			aIcons[i].className ="backgrounditem";
		}

		//set selected in picker
		get("liBackground_" + sBackground).className = "backgrounditem selected";

		//special icon version?
		if (this.logoOrIconSelected() == false || m_hasIconBackgrounds != true){
			sStyle = "url('images/backgrounds/preview/" + sBackground + ".png')";
		}else{
			sStyle = "url('images/backgrounds/preview/" + sBackground + "_icon.png')";
		}

		//change background
		get('divPreviewBackColour').style.background = sStyle;

		//set the selected radio button manually (IE6 refuses to respect images vs label  z-order)
		get("radBackground_" + sBackground).checked = true;

	}

	this.refreshBackground = function(){

		if(m_hasIconBackgrounds == true){
			var sStyle = get('divPreviewBackColour').style.background;
			sStyle = sStyle.replace(/(.png|_icon.png)/,"@wildcard@");
			if (this.logoOrIconSelected() == true){
				sStyle = sStyle.replace("@wildcard@","_icon.png");
			}else{
				sStyle = sStyle.replace("@wildcard@",".png");
			}
			get('divPreviewBackColour').style.background = sStyle;
		}
	}

	this.logoOrIconSelected = function(){
		var bReturn = false
		if(get("chkPartnerLogo").checked == true){
			bReturn= true;
		}

		if(get("radIcon_none").checked == false){
			bReturn= true;
		}
		return bReturn;
	}

 	this.changeIcon = function (sIcon){

		//set selected in icon picker
		var aIcons = document.getElementsByClassName('iconitem');
		for (var i=0; i < aIcons.length; i++) {
			aIcons[i].className ="iconitem";
		}

		get("liIcon_" + sIcon).className = "iconitem selected";

		//change icon on the card preview
		if (sIcon == 'none'){
			get('imgAvatarBack').style.display="none"
		}else if(sIcon == 'buddy'){
			get('imgAvatarBack').style.display="inline"
			get('imgAvatarBack').src = get('hidBuddyUrl').value
			get('imgAvatarBack').className = "partner buddy";
		}else{
			get('imgAvatarBack').style.display="inline"
			get('imgAvatarBack').src="images/icon/middle/" + sIcon + ".png";
			get('imgAvatarBack').className = "partner " +sIcon;
		}

		//set the selected radio button manually (IE6 refuses to respect images vs label  z-order)
		get("radIcon_" + sIcon).checked  = true;

		//Check for space and the card background
		this.checkAvalableSpace();
		this.refreshBackground();
	}

	this.changePartnerIcon = function (sIconId, sIconUrl){

		//set selected in icon picker
		var aIcons = document.getElementsByClassName('iconitem');
		for (var i=0; i < aIcons.length; i++) {
			aIcons[i].className ="iconitem";
		}

		get("liIcon_" + sIconId).className = "iconitem selected";

		//change icon on the card preview
		if (sIconId == 0){
			get('imgAvatarBack').style.display="none"
		}else{
			get('imgAvatarBack').style.display="inline"
			get('imgAvatarBack').src = "../crop.php?url=" + safeImage(sIconUrl) + "&max=48";
			get('imgAvatarBack').className = "partner " +sIconId;
			//get('imgAvatarBack').style.height = "48px";
			//get('imgAvatarBack').style.width = "48px";
		}

		//set the selected radio button manually (IE6 refuses to respect images vs label  z-order)
		get("radIcon_" + sIconId).checked  = true;

		//Check for space and the card background
		this.checkAvalableSpace();
		this.refreshBackground();
	}

	this.inverseColour = function(){

		var sTextColour = "";
		var sBackgroundColour = "";
		if (get('chkInverseColour').checked == true){
			sTextColour = "#ffffff";
			sBackgroundColour = '#' + get('hidTextColour').value;;
		}else{
			sTextColour = '#' + get('hidTextColour').value;
			sBackgroundColour = "#ffffff";
		}

		aPreviewtext = document.getElementsByClassName('previewline');
		for (i=0; i < aPreviewtext.length; i++) {
			aPreviewtext[i].style.color = sTextColour;
		 }

		get("divPreviewBackColour").style.background = sBackgroundColour;
	}

	this.selectMeta = function(iLineNumber){

		var sMetaType = get('ddlMetaToggle' + iLineNumber).value;
		var oTextbox = get('txtLine' + iLineNumber);

		//If it's freetext or divider, reselect "free text"
		if (sMetaType=="freetext" || sMetaType == "div"){
			get('ddlMetaToggle' + iLineNumber).value = "freetext";

			//enable textbox
			oTextbox.disabled=false;
			oTextbox.className = "textbox preview";
			oTextbox.value="";
			this.syncLine(iLineNumber);
			setFocus(oTextbox.id);
		}else{

			//clear & disable textbox
			oTextbox.disabled=true;
			oTextbox.className = "textbox preview disabled";
			oTextbox.style.backgroundPosition = "-250px";

			//Set full meta name
			this.setMetaFullName(iLineNumber);

			//Get meta data
			var aMetaValues = eval("(" + unescape_from_input_element(get('hidJsonMeta').value) + ")");
			var sMetaValue =  aMetaValues[sMetaType];

			//set example in card preview
			get('pLine' + iLineNumber).childNodes[0].innerHTML = sMetaValue;

			//Set wildcard in textbox
			get('hidLine' + iLineNumber).value = sMetaValue;
		}
	}

	this.setMetaFullName = function(iLineNumber){
		var sNiceName = dropdownTextValue('ddlMetaToggle' + iLineNumber);
		get('txtLine' + iLineNumber).value=sNiceName + " will appear on each card";
	}

	//validate
	this.validate=function (){
		postBackForm(m_sFormId);
	}

	this.checkAvalableSpace = function(){

		var bPartnerLogo = false
		if(m_HasDesignHasPartnerLogo == true){
			bPartnerLogo = ((get("chkPartnerLogo").checked)?true:false);
		}

		var bAvatar = false
		if (m_has_icons == true){
			bAvatar = get('radIcon_none').checked == false;
		}

		if (bPartnerLogo == true || bAvatar == true){
			//less room for text
			get("divPreviewtext").className = "";
		}else{
			//loadsaroom
			get("divPreviewtext").className = "wide";
		}

		this.syncAllLines();
	}

	//Colour picked
	this.textColourPicked = function(sColour){

		var bInverse = false;
		if(document.getElementById('chkInverseColour')){
			if(get('chkInverseColour').checked == true){
				bInverse = true;
			}
		}

		if (bInverse != true){

			aPreviewtext = document.getElementsByClassName('previewline');
			for (i=0; i < aPreviewtext.length; i++) {
				aPreviewtext[i].style.color = "#" + sColour;
			 }

			//set colour selected
			var aColours = document.getElementsByClassName('colouritem');
			for (var i=0; i < aColours.length; i++) {
				aColours[i].className ="colouritem";
			}
		}else{
			//set colour selected
			var aColours = document.getElementsByClassName('colouritem');
			for (var i=0; i < aColours.length; i++) {
				aColours[i].className ="colouritem";
			}
			get("divPreviewBackColour").style.background = "#" + sColour;
		}

		//post the variables;
		get('hidTextColour').value = sColour;

		//set item in toolbar
		get('liColour_' + sColour).className = "colouritem selected";
	}


	//This method is called when a user clicks on Previous on a card back page which has a number
	//of partner icons.  It's purpose is to hide the currently visible icons, and show the next set.
	this.showPrevPartnerIcons = function(){

		//Declare and Initialise the variables required for this method
		var firstVisibleIcon = get('hidPartnerIconPosition').value
		var lastVisibleIcon;
		var firstNewSetIcon;
		var lastNewSetIcon;
		var totalcards = get('hidPartnerIconCount').value;

		//Now we need to figure out the number of icons currently showing on the page,
		//and the number of icons we wish to show in the next set
		if (totalcards > eval(firstVisibleIcon) + eval(12)){

			//In here means that there are currently 12 icons showing on the page,
			//so we want to clear them all
			lastVisibleIcon = eval(firstVisibleIcon)+eval(12);

			if ((eval(firstVisibleIcon) - eval(12)) >= eval(0)){
				//in here means that we are not on the first page of icons.
				//so clicking prev will show the previous set of icons
				firstNewSetIcon = eval(firstVisibleIcon) - eval(12);
			}
			else{
				//in here means that we are on the first set of 12 icons.
				//we need to calculate the last icon start position
				var numOfSets = Math.floor(totalcards/12);
				firstNewSetIcon = (numOfSets) * 12;
			}
		}
		else{
			//We are currently showing less than 12 icons on the page, due to being at the
			//end of the user's list.  Clicking prev should take us back to start after clearing these
			lastVisibleIcon = eval(totalcards);
			firstNewSetIcon = eval(firstVisibleIcon) - eval(12);
		}

		//Now we need to figure out how many icons we are about to show
		if (totalcards > eval(firstNewSetIcon) + eval(12)){
			//12 icons to show
			lastNewSetIcon = eval(firstNewSetIcon) + eval(12);
		}
		else{
			//this has taken us to the end of the user's icons.  Only show those that remain
			lastNewSetIcon = eval(totalcards);
		}

		//Now we've calculated the start and end positions.  Do the showing and hiding
		//First the hiding
		for (var i = firstVisibleIcon; i < lastVisibleIcon; i++)
		{
			var currentIcon = get('liIcon_'+i);
			currentIcon.style.display = "none";
		}

		//Now the showing
		for (var i = firstNewSetIcon; i < lastNewSetIcon; i++)
		{
			var currentIcon = get('liIcon_'+i);
			currentIcon.style.display = "block";
		}

		//Set the current icon position value
		get('hidPartnerIconPosition').value = firstNewSetIcon;
	}

	//This method is called when a user clicks on Next on a card back page which has a number
	//of partner icons.  It's purpose is to hide the currently visible icons, and show the next set.
	//Nothing too clever really
	this.showNextPartnerIcons = function(){

		//Declare and Initialise the variables required for this method
		var firstVisibleIcon = get('hidPartnerIconPosition').value
		var lastVisibleIcon;
		var firstNewSetIcon;
		var lastNewSetIcon;
		var totalcards = get('hidPartnerIconCount').value;

		//Now we need to figure out the number of icons currently showing on the page,
		//and the number of icons we wish to show in the next set
		if (totalcards > eval(firstVisibleIcon) + eval(12)){

			//In here means that there are currently 12 icons showing on the page,
			//so we want to clear them all
			lastVisibleIcon = eval(firstVisibleIcon)+eval(12);
			if (totalcards > eval(firstVisibleIcon) + eval(12))
			{
				//in here means that we are not yet displaying the last icon.
				//so the next visible one is the next icon
				firstNewSetIcon = lastVisibleIcon;
			}
			else{
				//in here means that we are currently displaying the last user icon
				//on the page.  we need to show the first set again when user clicks next
				firstNewSetIcon = 0;
			}
		}
		else{
			//We are currently showing less than 12 icons on the page, due to being at the
			//end of the user's list.  Clicking next should take us back to start after clearing these
			lastVisibleIcon = eval(totalcards);
			firstNewSetIcon = 0;
		}

		//Now we need to figure out how many icons we are about to show
		if (totalcards > eval(firstNewSetIcon) + eval(12)){
			//12 icons to show
			lastNewSetIcon = eval(firstNewSetIcon) + eval(12);
		}
		else{
			//this has taken us to the end of the user's icons.  Only show those that remain
			lastNewSetIcon = eval(totalcards);
		}

		//Now we've calculated the start and end positions.  Do the showing and hiding
		//First the hiding
		for (var i = firstVisibleIcon; i < lastVisibleIcon; i++)
		{
			var currentIcon = get('liIcon_'+i);
			currentIcon.style.display = "none";
		}

		//Now the showing
		for (var i = firstNewSetIcon; i < lastNewSetIcon; i++)
		{
			var currentIcon = get('liIcon_'+i);
			currentIcon.style.display = "block";
		}

		//Set the current icon position value
		get('hidPartnerIconPosition').value = firstNewSetIcon;
	}



	//Constructor
	setFocus('txtLine1');
	this.syncAllLines();

}