

function DJMqeObject(setup) {
	var self = this;
	var rowTag = 'div';
	var cellTag = 'span';
	
	if (setup == undefined) return;
	
	this.setup = setup;
	this.mqeObject = null;
	this.fixedArea = null;
	this.scrollArea = null;
	this.className = {odd:'CZAA_txt', even:'CZAA_txt_rev', right:'CZAA_R', left:'', center:'CZAA_C', red:'textRed', green:'textGreen'};
	this.Template = {
		quote : {
			row: '<div class="ovf{0}" style="height:{1}px;{2}">{3}</div>',
			cell: '<span class="MqeCell{0}" style="width:{1}px;{2}">{3}</span>'		
		},
		news : {
			row: '<div class="ovf{0}" style="height:{1}px;{2}">{3}</div>',
			cell: '<span class="MqeCell{0}" style="width:{1}px;{2}">{3}</span>',
			cell2: '<span class="MqeCell{0}" style="width:{1}px;{2}"><a href="{4}{5}" {6}>{3}</a></span>'
		}
	};
	this.borderBottomStyle = 'solid #000000 1px';
	this.init = function() {
		self.mqeObject = document.getElementById(self.setup.renderTo);
		self.fixedArea = document.getElementById(self.setup.fixedArea);
		self.scrollArea = document.getElementById(self.setup.scrollArea);
		if (self.mqeObject == undefined) return;
		//Setup
		if (self.setup.type == undefined || self.setup.type == '') self.setup.type = 'quote';
		if (self.setup.type == 'news' && self.setup.linkTo == undefined) self.setup.linkTo = '';
		if (self.setup.type == 'news' && self.setup.linkTarget == undefined) self.setup.linkTarget = '';
		//UI
		self.mqeObject.style.width = self.setup.w + 'px';
		self.mqeObject.style.height = self.setup.h + 'px';
		self.HttpGetData(self.setup.dataSrc + ((self.setup.dataSrc.indexOf('?') == -1) ? '?' : '&')+'xyz=' + self.getTimeSeq(), self.initCallback)
	};
	this.initCallback = function(data) {
		var json = self.stringToJSON(data);
		var i, iMax = json.length;
		var sHtml = '';
		var sCell = '';
		var sHtmlScroll = '';
		var nSeparateIndex = -1;
		for (i=0; i<iMax; i+=1) {
			if (self.setup.type == 'quote') {
				if (json[i].v1.indexOf(' ') > -1) {
					var aCell = json[i].v1.split(' ');
					var j, jMax = aCell.length;
					if (jMax !== self.setup.cellWidth.length)
						return;
					sCell = '';
					for (j=0; j<jMax; j+=1) {
						//sCell += self.stringFormat(self.Template.cell, ((j==0) ? '' : ' ' + self.className.right) + ((aCell[j].indexOf('+')==0) ? ' ' + self.className.red : ((aCell[j].indexOf('-')==0) ? ' ' + self.className.green : '')), self.setup.cellWidth[j], '', ((j!==0) ? aCell[j] : encodeURIComponent(aCell[j])));
						if (!!self.setup.cellAlign) {
							sCell += self.stringFormat(
								self.Template.quote.cell, (!!!self.setup.cellAlign[j]? ((j==0)? '' : self.className.right) : ' ' + self.className[self.setup.cellAlign[j]]) + 
								((aCell[j].indexOf('+')==0) ? ' ' + self.className.red : ((aCell[j].indexOf('-')==0) ? ' ' + self.className.green : '')), self.setup.cellWidth[j],self.setup.cellStyle? self.setup.cellStyle : '', aCell[j]
							)
						}else {
							sCell += self.stringFormat(self.Template.quote.cell, ((j==0) ? '' : ' ' + self.className.right) + ((aCell[j].indexOf('+')==0) ? ' ' + self.className.red : ((aCell[j].indexOf('-')==0) ? ' ' + self.className.green : '')), self.setup.cellWidth[j], '', aCell[j]);
						}
					}
					if (nSeparateIndex === -1) {
						sHtml += self.stringFormat(self.Template.quote.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
					else {
						sHtmlScroll += self.stringFormat(self.Template.quote.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
				}
				else {
					if (json[i].v1 == self.setup.separate) {
						nSeparateIndex = i;
					}
				}
			}
			else if (self.setup.type == 'news') {
				if (json[i].v2 != undefined && json[i].v2 != '') {
					if (self.setup.linkTo == '')
						sCell = self.stringFormat(self.Template.news.cell, '', self.setup.cellWidth[0], '', json[i].v2);
					else
						sCell = self.stringFormat(self.Template.news.cell2, '', self.setup.cellWidth[0], '', json[i].v2, self.setup.linkTo, json[i].v1, self.setup.linkTarget);
					
					if (nSeparateIndex === -1) {
						sHtml += self.stringFormat(self.Template.news.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
					else {
						sHtmlScroll += self.stringFormat(self.Template.news.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
				}
				else {
					if (json[i].v1 == self.setup.separate) {
						nSeparateIndex = i;
					}
				}
			}
		}
		var fH=0, sH=0;
		//nSeparateIndex === -1 ，表示都沒有「-----」，則全部都固定
		if (self.fixedArea != undefined) {
			if (nSeparateIndex !== -1 )
				fH = nSeparateIndex*self.setup.cellHeight;
			else
				fH = self.setup.h;
			if (fH > self.setup.h) fH = self.setup.h;
			self.fixedArea.style.borderBottom = (self.setup.bottomStyle != undefined) ? self.setup.bottomStyle : self.borderBottomStyle;
		}
		sH = self.setup.h-fH;
		if (self.fixedArea != undefined) {
			self.fixedArea.style.width = self.setup.w +'px';
			self.fixedArea.style.height = fH+'px';
			self.fixedArea.innerHTML = sHtml;
		}
		if (nSeparateIndex !== -1 && self.scrollArea != undefined) {
			self.scrollArea.style.width = self.setup.w +'px';
			self.scrollArea.style.height = sH+'px';
			self.scrollArea.innerHTML = sHtmlScroll;
			self.startScroll();
		}
		if (typeof self.setup.onReady != 'undefined' && typeof self.setup.onReady == 'function') {
			self.setup.onReady();
		}
		setTimeout(function () {self.updateData();}, self.setup.updRate);
	};
	this.startScroll = function() {
		var delay = self.setup.delay||0;
		var speed = self.setup.speed||100;
		var h = self.setup.cellHeight;
		var tid = null;
		var pause = false;
		var fun = function() {tid = setInterval(doScroll, speed);}
		var doScroll = function() {
			if(pause) return;
			self.scrollArea.scrollTop += 1;
			//滾動到設定的高度就停一下(delay)，delay設成0就連續，設成1秒或2秒就很有廣告效果
			if(self.scrollArea.scrollTop%h == 0) {
				//先清timer
				clearInterval(tid);
				//把滾出去的div移到最後一位
				var oRows = self.scrollArea.getElementsByTagName(rowTag);
				var sChkClass = (self.hasClassName(oRows[0], self.className.odd)) ? self.className.odd : self.className.even;
				var sRevClass = (sChkClass !== self.className.odd) ? self.className.odd : self.className.even;
				if (self.hasClassName(oRows[oRows.length-1], sChkClass)) {
					self.replaceClassName(oRows[0], sChkClass, sRevClass);
				}
				if (oRows[0] !== undefined) {
					self.scrollArea.appendChild(oRows[0]);
				}
				self.scrollArea.scrollTop = 0;
				setTimeout(fun, delay);
			}
		}
		self.scrollArea.onmouseover = function() { pause = true;}
		self.scrollArea.onmouseout = function() { pause = false;}
		//Marquee Start
		setTimeout(fun, delay);
	};
	this.updateData = function() {
		self.HttpGetData(self.setup.dataSrc + ((self.setup.dataSrc.indexOf('?') == -1) ? '?' : '&')+'xyz=' + self.getTimeSeq(), self.updateDataCallback);
		setTimeout(function () {self.updateData();}, self.setup.updRate);
	};
	this.updateDataCallback = function(data) {
		var json = self.stringToJSON(data);
		var i, iMax = json.length;
		var bUpdScroll = false;
		var sHtml = '';
		var sCell = '';
		var sHtmlScroll = '';
		var nSeparateIndex = -1;
		for (i=0; i<iMax; i+=1) {
			if (self.setup.type == 'quote') {
				if (json[i].v1.indexOf(' ') > -1) {
					var aCell = json[i].v1.split(' ');
					var j, jMax = aCell.length;
					var oLineList;
					if (jMax !== self.setup.cellWidth.length)
						return;
					if (!bUpdScroll && self.fixedArea != undefined) {
						oLineList = self.fixedArea.getElementsByTagName(rowTag);
					}
					if (bUpdScroll && self.scrollArea != undefined) {
						oLineList = self.scrollArea.getElementsByTagName(rowTag);
					}
					if (oLineList == undefined)
						return;
					var k, kMax = oLineList.length;
					var sCell = '';
					for (k=0; k<kMax; k+=1) {
						if (oLineList[k].getElementsByTagName(cellTag)[0].innerHTML == aCell[0]) {
							sCell = '';
							for (j=0; j<jMax; j+=1) {
								sCell += self.stringFormat(self.Template.quote.cell, ((j==0) ? '' : ' ' + self.className.right) + ((aCell[j].indexOf('+')==0) ? ' ' + self.className.red : ((aCell[j].indexOf('-')==0) ? ' ' + self.className.green : '')), self.setup.cellWidth[j], '', aCell[j]);
							}
							oLineList[k].innerHTML = sCell;
						}
					}
				}
				else {
					if (json[i].v1 == self.setup.separate) {
						bUpdScroll = true;
					}
				}
			}
			else if (self.setup.type == 'news') {
				if (json[i].v2 != undefined && json[i].v2 != '') {
					if (self.setup.linkTo == '')
						sCell = self.stringFormat(self.Template.news.cell, '', self.setup.cellWidth[0], '', json[i].v2);
					else
						sCell = self.stringFormat(self.Template.news.cell2, '', self.setup.cellWidth[0], '', json[i].v2, self.setup.linkTo, json[i].v1, self.setup.linkTarget);
					
					if (nSeparateIndex === -1) {
						sHtml += self.stringFormat(self.Template.news.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
					else {
						sHtmlScroll += self.stringFormat(self.Template.news.row, (!!(i%2) ? ' ' + self.className.odd : ' ' + self.className.even), self.setup.cellHeight, '', sCell);
					}
				}
				else {
					if (json[i].v1 == self.setup.separate) {
						nSeparateIndex = i;
					}
				}
			}
		}
	};
	this.XmlHttpObj = null;
	this.HttpGetData = function(url) {
		var xmlhttp = self.XmlHttpObj;
		var callback = (arguments.length) > 1 ? arguments[1] : null;
		var async = (arguments.length) > 2 ? arguments[1] : true;
		var sData = "";
		
		if (xmlhttp == null) {
			// w3cschool
			if (window.XMLHttpRequest) {
				// code for IE7+, Firefox, Chrome, Opera, Safari
				xmlhttp = new XMLHttpRequest();
			}
			else {
				// code for IE6, IE5
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
			self.XmlHttpObj = xmlhttp;
		}
		
		xmlhttp.open("GET", url, async);
		xmlhttp.setRequestHeader("Content-Type", "text/json;charset=big5");
		xmlhttp.setRequestHeader("If-Modified-Since", "Wed, 15 Nov 1995 04:58:08 GMT")
		xmlhttp.onreadystatechange = function () {
			if (xmlhttp.readyState==4 && xmlhttp.status==200) {
				if (callback != null && typeof callback == 'function')
					callback(xmlhttp.responseText);
				else
					sData = xmlhttp.responseText;
			}
		}
		try {
			xmlhttp.send(null);
		}
		catch(e) {}
		if (callback == null || typeof callback != 'function')
			return sData;
	};
	this.jsonToString = function(obj) {
		var THIS = this; 
		switch(typeof(obj)){
			case 'string':
				return '"' + obj.replace(/(["\\])/g, '\\$1') + '"';
			case 'array':
				return '[' + obj.map(THIS.jsonToString).join(',') + ']';
			case 'object':
				if(obj instanceof Array){
					var strArr = [];
					var len = obj.length;
					for(var i=0; i<len; i++){
						strArr.push(THIS.jsonToString(obj[i]));
					}
					return '[' + strArr.join(',') + ']';
				}else if(obj==null){
					return 'null';

				}else{
					var string = [];
					for (var property in obj) string.push(THIS.jsonToString(property) + ':' + THIS.jsonToString(obj[property]));
						return '{' + string.join(',') + '}';
				}
			case 'number':
				return obj;
			case false:
				return obj;
		}
	};
	this.stringToJSON = function(obj) {
		return eval('(' + obj + ')');
	};
	this.stringFormat = function () {
		if (arguments.length == 0) {
			return null;
		}
		var str = arguments[0];
		for (var i=1, iMax=arguments.length; i<iMax; i+=1) {
			var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
			str = str.replace(re, arguments[i]);
		}
		return str;
	};
	this.getTimeSeq = function() {
		var d, yyyy, mm, dd, hh, MM, ss;
		d = new Date();
		yyyy = d.getFullYear().toString();
		mm = (d.getMonth() + 1).toString();
		dd = d.getDate().toString();
		hh = d.getHours().toString();
		MM = d.getMinutes().toString();
		ss = d.getSeconds().toString();
		return yyyy + (mm.charAt(1) ? mm : "0" + mm) + (dd.charAt(1) ? dd : "0" + dd) + (hh.charAt(1) ? hh : "0" + hh) + (MM.charAt(1) ? MM : "0" + MM) + (ss.charAt(1) ? ss : "0" + ss);
	};
	this.ConvertTimeSeq2Date = function (str) {
		return str.replace(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/,"$1/$2/$3 $4:$5:$6");
	}
	this.hasClassName = function(oEle, sClassName) {
		if (oEle === undefined) return;
		return oEle.className.match(new RegExp('(\\s|^)'+sClassName+'(\\s|$)'));
	};
	this.addClassName = function(oEle, sClassName) {
		if (!self.hasClassName(oEle, sClassName)) oEle.className += ' ' + sClassName;
	};
	this.removeClassName = function(oEle, sClassName) {
		if (self.hasClassName(oEle, sClassName)) {
			var reg = new RegExp('(\\s|^)'+sClassName+'(\\s|$)');
			oEle.className = oEle.className.replace(reg, ' ');
		}
	};
	this.replaceClassName = function(oEle, sFindClass, sReplaceWithClass) {
		if (self.hasClassName(oEle, sFindClass)) {
			var reg = new RegExp('(\\s|^)'+sFindClass+'(\\s|$)');
			oEle.className = oEle.className.replace(reg, ' ' + sReplaceWithClass);
		}
	};
	if (window.addEventListener) {
		window.addEventListener('load', function() { self.init(); }, false); 
	} else if (window.attachEvent) {
		window.attachEvent('onload', function() { self.init(); });
	}	
}

