Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
mw.loader.using( ['mediawiki.util', 'mediawiki.api', 'jquery.ui'], function () {
	if(mw.config.get('wgPageName').indexOf('Wikipedia:Arbitration/Requests/Case') != -1 &&
	   mw.config.get('wgTitle').indexOf('Proposed decision') != -1) {
	   	$(document).ready( function () {
			mw.util.addPortletLink( 'p-cactions', '#', 'ACImplNotes', 'ca-makeACNotes', 'Generate notes' );
		} );
		ACImplNotes = {};
		ACImplNotes.parse_item = function(section_text){
			// locate title
			var section_header_re = /^={3,}\s*([^=]*)?\s*={3,}$/m;
			var res = section_header_re.exec(section_text);
			var title = "";
			if(res === null){
				return null;
			}
			else {
				title = res[1];
			}
			var number_re = /^[^=]*?(\d[\w\.]*)\)/m;
			res = number_re.exec(section_text);
			var number = "";
			if(res === null){
				return null;
			}
			else {
				number = res[1];
			}
			var support_loc = section_text.indexOf('Support:');
			var oppose_loc = section_text.indexOf('Oppose:');
			var abstain_loc = section_text.indexOf('Abstain:');
			if(support_loc == -1 || oppose_loc == -1 || abstain_loc == -1){
				return null;
			}
			var support_txt = section_text.substring(support_loc, oppose_loc);
			var oppose_txt = section_text.substring(oppose_loc, abstain_loc);
			var abstain_txt = section_text.substring(abstain_loc);
			var vote_re = /^:#[^:*#].*?\w.*$/mg;
			cnt = function(arr){ if(arr === null) return 0; else return arr.length; };
			var result = { title: title, number:number,
			         support: cnt(support_txt.match(vote_re)),
			         oppose:  cnt(oppose_txt.match(vote_re)),
			          abstain: cnt(abstain_txt.match(vote_re))};
			if(result.title == "Template" && result.support === 0 && result.oppose === 0 && result.abstain === 0) {
				return null;
			}
			return result;
		};
		ACImplNotes.generate_proposal = function(data){
			if(data === null) return "";
			return "{" + "{ACImplNotes/Proposal |name= " + data.title +
			       "|number= " + data.number +
			       "|support= " + data.support +
			       "|oppose= " + data.oppose +
			       "|abstain= " + data.abstain +
			       "|notes= }}\n";
		};
		ACImplNotes.parse_sections = function(sections_txt){
			var section_header_re = /^={3,}\s*([^=]*)?\s*={3,}$/mg;
			var ret = "";
			var parse_result = section_header_re.exec(sections_txt);
			if(parse_result === null){
				alert("Can't find section headers.");
				return "";
			}
			var first_pos = parse_result.index;
			while((parse_result = section_header_re.exec(sections_txt)) !== null){
				ret += ACImplNotes.generate_proposal(ACImplNotes.parse_item(sections_txt.substring(first_pos, parse_result.index)));
				first_pos = parse_result.index;
			}
			ret += ACImplNotes.generate_proposal(ACImplNotes.parse_item(sections_txt.substring(first_pos)));
			return ret;
		};
		ACImplNotes.do_generate = function(page_text){
			var principles_re = /=\s*Proposed principles\s*=/;
			var fof_re = /=\s*Proposed findings of fact\s*=/;
			var remedies_re = /=\s*Proposed remedies\s*=/;
			var enforcement_re = /=\s*Proposed enforcement\s*=/;
			var principles_pos = page_text.search(principles_re);
			var fof_pos = page_text.search(fof_re);
			var remedies_pos = page_text.search(remedies_re);
			var enforcement_pos = page_text.search(enforcement_re);
			if(principles_pos == -1 || fof_pos == -1 || remedies_pos == -1 || enforcement_pos == -1) {
				alert('Cannot parse page: make sure that "Proposed principles", "Proposed findings of fact", "Proposed remedies", and "Proposed enforcement" sections are all present on the page');
				return "";
			}
			var result = "{" + "{ACImplNotes\n|updated= ~~" + "~~\n|principles=\n";
		    result += ACImplNotes.parse_sections(page_text.substring(principles_pos, fof_pos));
		    result += "|findings=\n";
		    result += ACImplNotes.parse_sections(page_text.substring(fof_pos, remedies_pos));
		    result += "|remedies=\n";
		    result += ACImplNotes.parse_sections(page_text.substring(remedies_pos, enforcement_pos));
		    result += "|enforcement=\n{" + "{ACImplNotes/Proposal |name=Enforcement of restrictions|number=0 |support=0 |oppose=0 |abstain=0 |pass=pass|notes=Passes by default }}\n";
		    result += "{" + "{ACImplNotes/Proposal |name=Appeals and modifications|number=0 |support=0 |oppose=0 |abstain=0 |pass=pass|notes=Passes by default }}\n}}";
		    return result;
		};
		ACImplNotes.onclick = function() {
			var api = new mw.Api();
			var params = {
				'action':'query',
				'prop':'revisions',
				'titles':mw.config.get('wgPageName'),
				'rvprop':'content'
			};
			api.get(params).done(function(data){
				var pageid = mw.config.get('wgArticleId').toString();
				var wikitext = data['query']['pages'][pageid]['revisions'][0]['*'];
				$( "#ACImplNotes-generated" ).html('<pre>' + ACImplNotes.do_generate(wikitext) +'</pre>');
				$( "#ACImplNotes-generated" ).show().dialog( { title: "Implementation notes",
				width:1000
				} );	
			});
			return false;
		};
		$(document).on('click', '#ca-makeACNotes', ACImplNotes.onclick);
		$('#Implementation_notes').after('&nbsp;&nbsp;<a href="#" id="makeimplnotes_link" style="font-size:small;font-weight:normal;">[Generate implementation notes]</a>');
		$(document).on('click', '#makeimplnotes_link', ACImplNotes.onclick);
		$('#bodyContent').before('<div id="ACImplNotes-generated" style="width:1000px;display:none;">'+
		'</div>');
	}
});