/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts)/*:WorkbookFile*/ {
	if(!data) throw new Error("Could not find file");
	var wb = { AppVersion:{}, WBProps:{}, WBView:[], Sheets:[], CalcPr:{}, Names:[], xmlns: "" };
	var pass = false, xmlns = "xmlns";
	var dname = {}, dnstart = 0;
	/*(data.match(tagregex)||[]).forEach */
	data.replace(tagregex, function xml_wb(x, idx) {
		var y/*:any*/ = parsexmltag(x);
		switch(strip_ns(y[0])) {
			case '': break;
			/* 18.2.13 fileVersion CT_FileVersion ? */
			case '': case '': break;
			/* 18.2.12 fileSharing CT_FileSharing ? */
			case '': break;
			/* 18.2.28 workbookPr CT_WorkbookPr ? */
			case '': delete y[0]; wb.WBProps = y; break;
			case '': break;
			/* 18.2.29 workbookProtection CT_WorkbookProtection ? */
			case '': break;
			/* 18.2.1  bookViews CT_BookViews ? */
			case '': case '': break;
			/* 18.2.30   workbookView CT_BookView + */
			case '': break;
			/* 18.2.20 sheets CT_Sheets 1 */
			case '': case '': break; // aggregate sheet
			/* 18.2.19   sheet CT_Sheet + */
			case '': break;
			/* 18.2.15 functionGroups CT_FunctionGroups ? */
			case '': break;
			/* 18.2.14   functionGroup CT_FunctionGroup + */
			case '': case '': break;
			/* 18.2.8    externalReference CT_ExternalReference + */
			case '': break;
			case '': case '': pass=false; break;
			/* 18.2.5    definedName CT_DefinedName + */
			case '': {
				dname.Ref = data.slice(dnstart, idx);
				wb.Names.push(dname);
			} break;
			case '': break;
			/* 18.2.2  calcPr CT_CalcPr ? */
			case '': delete y[0]; wb.CalcPr = y; break;
			case '': break;
			/* 18.2.16 oleSize CT_OleSize ? (ref required) */
			case '': case '': case '': break;
			/* 18.2.18 pivotCaches CT_PivotCaches ? */
			case '': case '': case '': break;
			/* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
			case '': case '': break;
			/* 18.2.22   smartTagType CT_SmartTagType ? */
			case '': break;
			/* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */
			case '': break;
			/* 18.2.26 webPublishObjects CT_WebPublishObjects ? */
			case '': case '': break;
			/* 18.2.25 webPublishObject CT_WebPublishObject ? */
			case '': case '': case '': break;
			/* 18.2.7    ext CT_Extension + */
			case '': pass=false; break;
			/* Others */
			case '': pass=false; break;
			default: if(!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook');
		}
		return x;
	});
	if(XMLNS.main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);
	parse_wb_defaults(wb);
	return wb;
}
var WB_XML_ROOT = writextag('workbook', null, {
	'xmlns': XMLNS.main[0],
	//'xmlns:mx': XMLNS.mx,
	//'xmlns:s': XMLNS.main[0],
	'xmlns:r': XMLNS.r
});
function safe1904(wb/*:Workbook*/)/*:string*/ {
	/* TODO: store date1904 somewhere else */
	if(!wb.Workbook) return "false";
	if(!wb.Workbook.WBProps) return "false";
	// $FlowIgnore
	return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false";
}
function write_wb_xml(wb/*:Workbook*/, opts/*:?WriteOpts*/)/*:string*/ {
	var o = [XML_HEADER];
	o[o.length] = WB_XML_ROOT;
	var write_names = (wb.Workbook && (wb.Workbook.Names||[]).length > 0);
	/* fileVersion */
	/* fileSharing */
	o[o.length] = (writextag('workbookPr', null, {date1904:safe1904(wb), codeName:"ThisWorkbook"}));
	/* workbookProtection */
	/* bookViews */
	o[o.length] = "";
	var sheets = wb.Workbook && wb.Workbook.Sheets || [];
	for(var i = 0; i != wb.SheetNames.length; ++i) {
		var sht = ({name:escapexml(wb.SheetNames[i].substr(0,31))}/*:any*/);
		sht.sheetId = ""+(i+1);
		sht["r:id"] = "rId"+(i+1);
		if(sheets[i]) switch(sheets[i].Hidden) {
			case 1: sht.state = "hidden"; break;
			case 2: sht.state = "veryHidden"; break;
		}
		o[o.length] = (writextag('sheet',null,sht));
	}
	o[o.length] = "";
	/* functionGroups */
	/* externalReferences */
	if(write_names) {
		o[o.length] = "";
		if(wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function(n) {
			var d/*:any*/ = {name:n.Name};
			if(n.Comment) d.comment = n.Comment;
			if(n.Sheet != null) d.localSheetId = ""+n.Sheet;
			if(!n.Ref) return;
			o[o.length] = writextag('definedName', String(n.Ref), d);
		});
		o[o.length] = "";
	}
	/* calcPr */
	/* oleSize */
	/* customWorkbookViews */
	/* pivotCaches */
	/* smartTagPr */
	/* smartTagTypes */
	/* webPublishing */
	/* fileRecoveryPr */
	/* webPublishObjects */
	/* extLst */
	if(o.length>2){ o[o.length] = ''; o[1]=o[1].replace("/>",">"); }
	return o.join("");
}