class CBHeader {
	constructor(header, arrow_down, arrow_up) {
		this.header = header;
		this.logo = this.header.querySelector('a'); //Header part 1
		this.burgerBtn = this.header.querySelector('button'); //Header part 2
		this.mainMenu = this.header.querySelector('ul'); //Header part 3
		this.loginMenu = this.header.querySelector('nav'); //Header part 4
		this.arrow_down = arrow_down;
		this.arrow_up = arrow_up;
	}

	init() {
		window.addEventListener('resize', (e) => {
			this.checkResponsive();
		});
		this.checkResponsive();
		this.toggleMobileMenu();
	}

	checkResponsive() {
		const width = window.innerWidth;
		if (
			width <= 1100 && this.header.classList.contains('mobile') ||
			width > 1100 && !this.header.classList.contains('mobile')
		) {
			return;
		}

		//Remove the header content
		this.header.innerHTML = '';

		//Add the mobile menu and login menu to the mobile wrapper
		if (width <= 1100) {
			this.header.classList.add('mobile');
			let mobileWrapper = document.createElement('section');
			let mobileMenu = this.mainMenu.cloneNode(true);

			//Add arrow icons to the menu items that have children
			mobileMenu.querySelectorAll('li').forEach(el => {
				if (el.querySelector('ul') !== null) {
					el.querySelector('a').insertAdjacentHTML('afterend', `<button onclick="this.parentNode.classList.toggle('active');">${this.arrow_down}</button>`);
				}
			});

			//Add the mobile menu and login menu to the mobile wrapper
			mobileWrapper.append(mobileMenu, this.loginMenu);
			this.header.append(this.logo, this.burgerBtn, mobileWrapper);
			this.toggleMobileSubMenu();
		}

		//Add the desktop menu and login menu to the header
		if (width > 1100) {
			this.header.classList.remove('mobile');
			this.header.append(this.logo, this.mainMenu, this.loginMenu);
		}
	}

	toggleMobileMenu() {
		this.header.querySelector('button').addEventListener('click', (e) => {
			e.preventDefault();
			this.header.classList.toggle('active');

			//Close all submenus when the mobile menu is closed
			if (!this.header.classList.contains('active')) {
				this.header.querySelector('nav').querySelector('button').classList.remove('active');
				this.header.querySelectorAll('section > ul > li').forEach(el => {
					el.classList.remove('active');
				});
			}
		});
	}

	toggleMobileSubMenu() {
		// this.header.querySelectorAll('section > ul > li > a').forEach(el => {
		// 	const parent = el.parentElement;
		// 	if (parent.querySelector('ul'))
		// 		el.addEventListener('click', (e) => {
		// 			if (!parent.classList.contains('active')) {
		// 				e.preventDefault();
		// 				parent.classList.toggle('active');
		// 			}
		// 		});
		// });
	}
}

CBFooter = function () {
	//Handle scroll to anchor links with offset.
	function scrollToAnchor(elName) {
		const targetElement = document.querySelector(`a[name=${elName}]`);
		if (targetElement) {
			const headerOffset = 80;
			const elementPosition = targetElement.getBoundingClientRect().top + window.scrollY;
			const offsetPosition = elementPosition - headerOffset;
			window.scrollTo({
				top: offsetPosition,
				behavior: "smooth"
			});
		}
	}

	//Add event sto links with hash
	document.querySelectorAll('a[href^="#"]').forEach(anchor => {
		anchor.addEventListener("click", function (e) {
			e.preventDefault();
			const elName = this.getAttribute("href").substring(1);
			scrollToAnchor(elName);
		});
	});

	//Scroll to anchor if hash is present in URL
	if (window.location.hash) {
		setTimeout(() => {
			const elName = window.location.hash.substring(1);
			scrollToAnchor(elName);
		}, 100); // Small delay to ensure the page is loaded before scrolling
	}
}

function CBError(errors){
	var _errno=null;
	var _error=null;
	function errno(){return _errno;}
	function error(){return _error;}
	function reset(){_errno=null;error=null;}
	function set(errno,replaceObj,ret){
		_errno=errno;
		_error=errors[errno];
		for(let i in replaceObj){
			_error=_error.replace('{'+i+'}',replaceObj[i]);
		}
		if(typeof(ret)=='undefined'){ret=false;}
		return ret;
	}
	return {
		errno	:errno,
		error	:error,
		reset	:reset,
		set		:set
	}
}


CBNavigationSecondary = new function () {
    this.init = function () {
        let els = document.querySelectorAll('section[rel="CBNavigationSecondary"] ul');
        els.forEach(el => {
            if (!el.classList.contains('loaded')) {
                el.addEventListener('wheel', function (event) {
                    if (event.deltaY !== 0) {
                        this.scrollBy({
                            left: event.deltaY,
                            behavior: 'smooth'
                        });
                        event.preventDefault();
                    }
                });
                el.classList.add('loaded');
            }
        });
    }
}

function CBBSPSharePriceWidget_Data(data,marketData,CBMath){
	function draw_data(p,y_min,y_max,x_min,x_max,forceMin){
		var ret=[];var rx=[];var ry=[];
		for(let i=0;i<data.length;i++){
			rx.push(i);
			ry.push(data[i][p]);
		}
		var min=Math.min(...ry.filter(num=>num!==null));
		var max=Math.max(...ry.filter(num=>num!==null));
		if(typeof(forceMin)!='undefined'){
			min=forceMin;
		}
		var norm_x=CBMath.normalise(x_min,x_max,0,data.length-1,rx);
		var norm_y=CBMath.normalise(y_max,y_min,min,max,ry);
		for(let i=0;i<data.length;i++){
			ret.push({
				x:norm_x[i],
				y:norm_y[i],
				label_x:data[i].date,
				label_y:data[i][p]
			});
		}
		return ret;
	};
	function volumeYAxis(	){
		var volume=[];
		for(let i=0;i<data.length;i++){	volume.push(data[i].volume);	}
		var tmp=CBMath.min_max(volume);
		return {min:0,max:tmp.max};
	}
	function pricesYAxis(points){
		var prices=[];
		for(let i=0;i<data.length;i++){	prices.push(data[i].close);		}
		var tmp=CBMath.min_max(prices);
		var max=tmp.max;
		var min=tmp.min;
		var diff=max-min;
		var step=diff/(points-1);
		var ret=[min];
		var here=min;
		for(let i=3;i<=points;i++){
			here+=step;
			ret.push(here);
		}
		ret.push(max);
		return ret;
	}
	function xAxis(){
		var pick=6;		var total=data.length;
		var index=0;	var step=0;
		if(total<pick){
			step=1;
		}else{
			step=(total-1)/(pick-1);
		}
		var ret=[];
		for(let i=0;i<pick;i++){
			index=Math.round(i*step);
			ret.push(data[index].date);
		}
		return ret;
	}
	function market(){
		return marketData;
	}

	return {
		draw_data:draw_data,
		volumeYAxis:volumeYAxis,
		pricesYAxis:pricesYAxis,
		xAxis:xAxis,
		market:market
	};
}


function CBBSPSharePriceWidget_View(
	templates,volumeWidth,CBSVG,CBMath
){
	function labelY(lineTopEl,lineBottomEl,chartsEl,labelEl){
		var top=CBSVG.elementToDOMXY(lineTopEl		,'x1','y1');
		var bot=CBSVG.elementToDOMXY(lineBottomEl	,'x1','y1');
		var dst=bot.y-top.y;
		var mar=(dst-labelEl.offsetWidth)/2;
		mar+=top.y;
		labelEl.style.top=mar+'px';
	}
	function seriesLabelY(lineEl,labelEl,value,decimals){
		labelEl.innerHTML=CBMath.to_human(CBMath.n_significant_digits(value,3),decimals);
		var mid=CBSVG.elementToDOMXY(lineEl,'x1','y1');
		var pos=mid.y-labelEl.offsetHeight/2;
		labelEl.style.top=pos+'px';
		labelEl.style.left=(mid.x-labelEl.offsetWidth)+'px';
	}
	function seriesLabelX(lineEl,labelEls,data){
		var display=_dateFormat(data);
		var lft=CBSVG.elementToDOMXY(lineEl	,'x1','y1');
		var rgt=CBSVG.elementToDOMXY(lineEl	,'x2','y2');
		var container=rgt.x-lft.x;
		var positions=[];	var alignment=null;	var left=0;	var width=null;
		for(let i=0;i<data.length;i++){
			labelEls[i].innerHTML=display[i];
			width=labelEls[i].offsetWidth;
			alignment=(i/(data.length-1))*container;
			if(			i===0				){	left=alignment										;}
			else if(	i===data.length-1	){	left=alignment-		labelEls[i].offsetWidth			;}
			else{								left=alignment-(	labelEls[i].offsetWidth/2	)	;}
			labelEls[i].style.left=(lft.x+left)+'px';
			labelEls[i].style.top=lft.y+'px';
		}
	}
	function chartPrice(el,points){
		var tmp='';var str=null;var end=null;
		for(let i=0;i<points.length-1;i++){
			str=i;
			end=i+1;
			if(points[str].y!==null&&points[end].y!==null){
				tmp+=templates.price.innerHTML
					.replace('{x1}',points[str].x).replace('{y1}',points[str].y)
					.replace('{x2}',points[end].x).replace('{y2}',points[end].y);
				continue;
			}
			if(points[str].y!==null&&points[end].y===null){
				while(points[end].y===null){		end++;	}
				tmp+=templates.price.innerHTML
					.replace('{x1}',points[str].x).replace('{y1}',points[str].y)
					.replace('{x2}',points[end].x).replace('{y2}',points[end].y);
				i=end-1;
				continue;
			}
		}
		el.innerHTML=tmp;
	}
	function chartVolume(el,zeroLine,points){
		var tmp='';
		for(let i=0;i<points.length;i++){
			if(points[i].y===null){continue;}
			tmp+=templates.volume.innerHTML.replace('{x}',points[i].x-volumeWidth/2).replace('{y}',points[i].y).replace('{h}',zeroLine-points[i].y);
		}
		el.innerHTML=tmp;
	}

	function marketShare(els,share_price,change,pct_change,market_cap,high_52_week,low_52_week){
		els.price			.textContent=share_price;
		els.change.change	.textContent=change;
		els.change.pct		.textContent=pct_change;
		els.cap				.textContent=market_cap;
		els.high			.textContent=high_52_week;
		els.low				.textContent=low_52_week;
	}

	function _dateFormat(data){
		var years=[];	var months=[];	var tmp=null;
		for(let i=0;i<data.length;i++){
			tmp=data[i].split('-');		years.push(tmp[0]);				months.push(tmp[1]);
		}
		years=[...new Set(years)];		months=[...new Set(months)];
		years=years.length===1?true:false;	months=months.length===1?true:false;
		var InDate=null;var display=[];var prev_m=null;var prev_y=null;
		if(years&&months){
			InDate=new Date(data[0]);
			display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
			for(let i=1;i<data.length;i++){
				InDate=new Date(data[i]);
				display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
			}
			return display;
		}
		if((!years&&!months)||(!years&&months)){
			for(let i=0;i<data.length;i++){
				InDate=new Date(data[i]);
				tmp=data[i].split('-');
				if(tmp[0]===prev_y&&tmp[1]===prev_m){
					display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
				}else if(tmp[0]===prev_y&&tmp[1]!==prev_m){
					display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
					prev_m=tmp[1];
				}else{
					display.push(InDate.toLocaleDateString('en-GB',{year:'numeric',month:'short',day:'numeric'}));
					prev_y=tmp[0];
					prev_m=tmp[1];
				}
			}
			return display;
		}
		if(years&&!months){
			for(let i=0;i<data.length;i++){
				InDate=new Date(data[i]);
				tmp=data[i].split('-');
				if(tmp[1]===prev_m){
					display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
				}else{
					display.push(InDate.toLocaleDateString('en-GB',{month:'short',day:'numeric'}));
					prev_m=tmp[1];
				}
			}
			return display;
		}
		return false;
	}

	function selector(backEl,foreEl,selector){
		var lft=parseFloat(backEl.getAttribute('x'));
		var rgt=parseFloat(backEl.getAttribute('width'))-lft;
		var pad=parseFloat(foreEl.getAttribute('cy'));
		if(selector==='pngx'){
			foreEl.setAttribute('cx',pad+lft);
			return;
		}
		foreEl.setAttribute('cx',rgt-pad);
	}

	function range(rangeEls,selected){
		for(let i in rangeEls){
			rangeEls[i].classList.remove('sel');
		}
		rangeEls[selected].classList.add('sel');
	}

	function interactiveClear(interactiveEl,interactiveDomEl){
		interactiveEl.innerHTML='';interactiveDomEl.innerHTML='';
	}

	function interactive(
			interactiveEl,		position,	volume,
			interactiveDomEl,	date,		price,	currency,
			topY, bottomY,		clientX,	clientY
	){
		position=position==638?638-2.5:(position==60?60+2.5:position);	/*	@todo fulvio refactor this to use chartDims	*/
		interactiveEl.innerHTML=templates.interactive.line.innerHTML
			.replace('{x1}',position).replace('{y1}',topY)
			.replace('{x2}',position).replace('{y2}',bottomY);
		var InDate=new Date(date);
		date=InDate.toLocaleDateString('en-AU',{year:'numeric',month:'short',day:'numeric',weekday:'short'});
		volume=volume.toLocaleString('en-AU');
		if(price===null){
			currency='';
			price='N/A';
		}else{
			price=price.toFixed(2);
		}
		interactiveDomEl.innerHTML=templates.interactive.box.innerHTML
			.replace('{date}',date)
			.replace('{currency}',currency).replace('{price}',price)
			.replace('{volume}',volume);

							interactiveDomEl.className='right'		;
		if(position>319){	interactiveDomEl.className=''			;	clientX-=interactiveDomEl.offsetWidth;}
		interactiveDomEl.style=`top:${clientY}px;left:${clientX}px`;
	}

	return {
		labelY:labelY,
		seriesLabelY:seriesLabelY,
		seriesLabelX:seriesLabelX,
		chartPrice:chartPrice,
		chartVolume:chartVolume,
		marketShare:marketShare,
		selector:selector,
		range:range,
		interactiveClear:interactiveClear,
		interactive:interactive
	}
}


function CBBSPSharePriceWidget_Ctrl(
	svgEls,
	labelEls,
	rangeEls,
	selectorEls,
	marketEls,
	templateEls,
	data,
	CBMath,
	CBSVG
){
	var selector='pngx';
	var period='1';

	var periodToElement={'1':'r1m','Y':'rYtd','5':'r5y','A':'rAll'};
	var elementToPeriod=Object.fromEntries(Object.entries(periodToElement).map(function([key,value]){
		return [value,key];
	}));

	function _parseVolumeWidth(){
		var txt=templateEls.volume.textContent;
		var P=new DOMParser();
		var Doc=P.parseFromString(txt,templateEls.volume.getAttribute('type'));
		var w=Doc.querySelector('rect').getAttribute('width');
		return parseFloat(w);
	}
	var _volumeWidth=_parseVolumeWidth();

	var _V=CBBSPSharePriceWidget_View(templateEls,_volumeWidth,CBSVG,CBMath);

	var _D=null;
	var _bp=null;
	var _bv=null;
	var _Prices=null;
	var _Volume=null;

	function reload(){
		_D=CBBSPSharePriceWidget_Data(data[selector][period],data[selector].market_data,CBMath);
		_bp		=svgEls.price	.lines;
		_bv		=svgEls.volume	.lines;
		_Prices	=_D.draw_data('close'	,
			_bp[4].getAttribute('y1'),_bp[0].getAttribute('y1'),_bp[0].getAttribute('x1')+_volumeWidth,_bp[0].getAttribute('x2')-_volumeWidth
		);
		_Volume	=_D.draw_data('volume'	,
			_bv[1].getAttribute('y1'),_bv[0].getAttribute('y1'),_bv[0].getAttribute('x1')+_volumeWidth,_bv[0].getAttribute('x2')-_volumeWidth,
			0
		);
		_V.chartPrice(	svgEls.price	.chart,_Prices);
		_V.chartVolume(	svgEls.volume	.chart,parseFloat(_bv[0].getAttribute('y1')),_Volume);
	}
	reload();

	function refresh(){
		_V.labelY(	svgEls.price	.lines[4]	,svgEls.price	.lines[0]	,svgEls.charts	,labelEls.price		.text);
		_V.labelY(	svgEls.volume	.lines[0]	,svgEls.volume	.lines[1]	,svgEls.charts	,labelEls.volume	.text);
		var t=_D.pricesYAxis(5);
		for(let i=0;i<5;i++){
			_V.seriesLabelY(	svgEls.price	.lines[i]	,labelEls.price		.labels[i]	,t[i]	,2);
		}
		t=_D.volumeYAxis();
		t=[t.min,t.max];
		for(let i=0;i<2;i++){
			_V.seriesLabelY(	svgEls.volume	.lines[i]	,labelEls.volume	.labels[i]	,t[i]	,0);
		}
		_V.seriesLabelX(svgEls.volume.lines[0],labelEls.xAxis.labels,_D.xAxis());
		t=data[selector].market_data;
		_V.marketShare(marketEls,t.share_price,t.change,t.pctChange,t.market_cap,t.high_52_week,t.low_52_week);
		_V.selector(selectorEls.background,selectorEls.foreground,selector);
		_V.range(rangeEls,periodToElement[period]);
	}
	refresh();

	window					.addEventListener('scroll'	,refresh		);
	window					.addEventListener('resize'	,refresh		);
	selectorEls.selector	.addEventListener('click'	,toggleSource	);
	rangeEls.r1m			.addEventListener('click'	,r1m			);
	rangeEls.rYtd			.addEventListener('click'	,rYtd			);
	rangeEls.r5y			.addEventListener('click'	,r5y			);
	rangeEls.rAll			.addEventListener('click'	,rAll			);

	function toggleSource(	){selector=selector==='pngx'?'asx':'pngx';reload();refresh();}
	function r1m(			){period='1';reload();refresh();}
	function rYtd(			){period='Y';reload();refresh();}
	function r5y(			){period='5';reload();refresh();}
	function rAll(			){period='A';reload();refresh();}

	svgEls.price.chart	.addEventListener(	'mousemove'	,mouseMove	);
	svgEls.volume.chart	.addEventListener(	'mousemove'	,mouseMove	);
	svgEls.charts		.addEventListener(	'mouseout'	,mouseOut	);
	window				.addEventListener(	'blur'		,windowBlur	);

	function mouseOut(event	){if(event.target!=svgEls.charts){return;}windowBlur();}
	function windowBlur(	){_V.interactiveClear(svgEls.interactive,labelEls.interactive);}

	var _debounce=true;
	function debounce(){
		var now=Date.now();
		if(now-_debounce>16){_debounce=now;return true;}
		return false;
	}

	var _svgPoint	=svgEls.charts.createSVGPoint();
	var _svgSnap	=svgEls.charts.createSVGPoint();
	function mouseMove(event){
		if(debounce()===false){return;}
		_svgPoint.x=event.clientX;_svgPoint.y=event.clientY;
		var svgCoords=_svgPoint.matrixTransform(svgEls.charts.getScreenCTM().inverse());
		var selected=null;var diff=Infinity;var tmp=null;
		for(let i=0;i<_Prices.length;i++){
			tmp=Math.abs(_Prices[i].x-svgCoords.x);
			if(tmp<diff){diff=tmp;selected=i;}
		}
		_svgSnap.x=_Prices[selected].x;
		_svgSnap.y=_svgPoint.y;
		_svgSnap=_svgSnap.matrixTransform(svgEls.charts.getScreenCTM());
		var tmp=_svgSnap.x;
		if(selected===null){return;}
		_V.interactive(
			svgEls.interactive,			_Prices[selected].x,		_Volume[selected].label_y,
			labelEls.interactive,		_Prices[selected].label_x,	_Prices[selected].label_y,	selector==='pngx'?'K':'AU$',
			_bp[4].getAttribute('y1'),	_bv[0].getAttribute('y1'),	tmp,						event.clientY
		);
	}
}



var CBMathTools={
	normalise:function(dst_min,dst_max,src_min,src_max,src){
		if(src===null){return null;}
		if(typeof(src)==='number'){
			return dst_max-(src_max-src)*(dst_max-dst_min)/(src_max-src_min);
		}
		if(Array.isArray(src)){
			var ret=[];
			for(let i=0;i<src.length;i++){
				ret.push(CBMathTools.normalise(dst_min,dst_max,src_min,src_max,src[i]));
			}
			return ret;
		}
		return false;
	},
	n_significant_digits:function(num,digits){
		if(Array.isArray(num)){
			var ret=[];
			for(let i=0;i<num.length;i++){
				ret.push(CBMathTools.n_significant_digits(num[i],digits));
			}
			return ret;
		}
		if(typeof(num)==='number'){
			var factor=Math.pow(10,Math.floor(Math.log10(num))+1-digits);
			if(factor==0){return num;}
			return Math.round(num/factor)*factor;
		}
		return false;
	},
	min_max:function(num_array){
		var min=Infinity;var max=-Infinity;
		for(let i=0;i<num_array.length;i++){
			if(num_array[i]===null	){	continue			;}
			if(num_array[i]<min		){	min=num_array[i]	;}
			if(num_array[i]>max		){	max=num_array[i]	;}
		}
		return {min:min,max:max};
	},
	to_human:function(num,decimals){
		if(Array.isArray(num)){
			var ret=[];
			for(let i=0;i<num.length;i++){
				ret.push(CBMathTools.to_human(num[i]));
			}
			return ret;
		}
		if(typeof(num)==='number'){
			if(num>=1000000000	){	return (num/1000000000	).toFixed(decimals)+'B'	;}
			if(num>=1000000		){	return (num/1000000		).toFixed(decimals)+'M'	;}
			if(num>=1000		){	return (num/1000		).toFixed(decimals)+'K'	;}
			if(num>=100			){	return 	num				.toFixed(decimals)		;}
			if(num>=10			){	return 	num				.toFixed(decimals)		;}
									return	num				.toFixed(decimals)		;
		}
		return false;
	}
};


var CBSVGTools={
	elementToDOMXY:function(el,attribX,attribY){
		var ctm=el.getScreenCTM();
		var svgPoint=new DOMPoint(
			el.getAttribute(attribX),
			el.getAttribute(attribY)
		);
		var domPoint=svgPoint.matrixTransform(ctm);
		return {x:domPoint.x,y:domPoint.y};
	}
};


function CBDividendPaymentHistory(switchElement, table1, table2) {
    switchElement.addEventListener('change', function (e) {
        table1.style.display = e.target.checked ? 'none' : 'table';
        table2.style.display = e.target.checked ? 'table' : 'none';
    });
}
