package sml

import (
	"encoding/xml"
	"fmt"
	"strconv"
)

type CT_WorkbookPr struct {
	// Date 1904
	Date1904Attr *bool
	// Show Objects
	ShowObjectsAttr ST_Objects
	// Show Border Unselected Table
	ShowBorderUnselectedTablesAttr *bool
	// Filter Privacy
	FilterPrivacyAttr *bool
	// Prompted Solutions
	PromptedSolutionsAttr *bool
	// Show Ink Annotations
	ShowInkAnnotationAttr *bool
	// Create Backup File
	BackupFileAttr *bool
	// Save External Link Values
	SaveExternalLinkValuesAttr *bool
	// Update Links Behavior
	UpdateLinksAttr ST_UpdateLinks
	// Code Name
	CodeNameAttr *string
	// Hide Pivot Field List
	HidePivotFieldListAttr *bool
	// Show Pivot Chart Filter
	ShowPivotChartFilterAttr *bool
	// Allow Refresh Query
	AllowRefreshQueryAttr *bool
	// Publish Items
	PublishItemsAttr *bool
	// Check Compatibility On Save
	CheckCompatibilityAttr *bool
	// Auto Compress Pictures
	AutoCompressPicturesAttr *bool
	// Refresh all Connections on Open
	RefreshAllConnectionsAttr *bool
	// Default Theme Version
	DefaultThemeVersionAttr *uint32
}

func NewCT_WorkbookPr() *CT_WorkbookPr {
	ret := &CT_WorkbookPr{}
	return ret
}

func (m *CT_WorkbookPr) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	if m.Date1904Attr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "date1904"},
			Value: fmt.Sprintf("%d", b2i(*m.Date1904Attr))})
	}
	if m.ShowObjectsAttr != ST_ObjectsUnset {
		attr, err := m.ShowObjectsAttr.MarshalXMLAttr(xml.Name{Local: "showObjects"})
		if err != nil {
			return err
		}
		start.Attr = append(start.Attr, attr)
	}
	if m.ShowBorderUnselectedTablesAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "showBorderUnselectedTables"},
			Value: fmt.Sprintf("%d", b2i(*m.ShowBorderUnselectedTablesAttr))})
	}
	if m.FilterPrivacyAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "filterPrivacy"},
			Value: fmt.Sprintf("%d", b2i(*m.FilterPrivacyAttr))})
	}
	if m.PromptedSolutionsAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "promptedSolutions"},
			Value: fmt.Sprintf("%d", b2i(*m.PromptedSolutionsAttr))})
	}
	if m.ShowInkAnnotationAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "showInkAnnotation"},
			Value: fmt.Sprintf("%d", b2i(*m.ShowInkAnnotationAttr))})
	}
	if m.BackupFileAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "backupFile"},
			Value: fmt.Sprintf("%d", b2i(*m.BackupFileAttr))})
	}
	if m.SaveExternalLinkValuesAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "saveExternalLinkValues"},
			Value: fmt.Sprintf("%d", b2i(*m.SaveExternalLinkValuesAttr))})
	}
	if m.UpdateLinksAttr != ST_UpdateLinksUnset {
		attr, err := m.UpdateLinksAttr.MarshalXMLAttr(xml.Name{Local: "updateLinks"})
		if err != nil {
			return err
		}
		start.Attr = append(start.Attr, attr)
	}
	if m.CodeNameAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "codeName"},
			Value: fmt.Sprintf("%v", *m.CodeNameAttr)})
	}
	if m.HidePivotFieldListAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "hidePivotFieldList"},
			Value: fmt.Sprintf("%d", b2i(*m.HidePivotFieldListAttr))})
	}
	if m.ShowPivotChartFilterAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "showPivotChartFilter"},
			Value: fmt.Sprintf("%d", b2i(*m.ShowPivotChartFilterAttr))})
	}
	if m.AllowRefreshQueryAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "allowRefreshQuery"},
			Value: fmt.Sprintf("%d", b2i(*m.AllowRefreshQueryAttr))})
	}
	if m.PublishItemsAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "publishItems"},
			Value: fmt.Sprintf("%d", b2i(*m.PublishItemsAttr))})
	}
	if m.CheckCompatibilityAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "checkCompatibility"},
			Value: fmt.Sprintf("%d", b2i(*m.CheckCompatibilityAttr))})
	}
	if m.AutoCompressPicturesAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "autoCompressPictures"},
			Value: fmt.Sprintf("%d", b2i(*m.AutoCompressPicturesAttr))})
	}
	if m.RefreshAllConnectionsAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "refreshAllConnections"},
			Value: fmt.Sprintf("%d", b2i(*m.RefreshAllConnectionsAttr))})
	}
	if m.DefaultThemeVersionAttr != nil {
		start.Attr = append(start.Attr, xml.Attr{Name: xml.Name{Local: "defaultThemeVersion"},
			Value: fmt.Sprintf("%v", *m.DefaultThemeVersionAttr)})
	}
	e.EncodeToken(start)
	e.EncodeToken(xml.EndElement{Name: start.Name})
	return nil
}

func (m *CT_WorkbookPr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	// initialize to default
	for _, attr := range start.Attr {
		if attr.Name.Local == "codeName" {
			parsed, err := attr.Value, error(nil)
			if err != nil {
				return err
			}
			m.CodeNameAttr = &parsed
			continue
		}
		if attr.Name.Local == "date1904" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.Date1904Attr = &parsed
			continue
		}
		if attr.Name.Local == "hidePivotFieldList" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.HidePivotFieldListAttr = &parsed
			continue
		}
		if attr.Name.Local == "showBorderUnselectedTables" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.ShowBorderUnselectedTablesAttr = &parsed
			continue
		}
		if attr.Name.Local == "showPivotChartFilter" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.ShowPivotChartFilterAttr = &parsed
			continue
		}
		if attr.Name.Local == "promptedSolutions" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.PromptedSolutionsAttr = &parsed
			continue
		}
		if attr.Name.Local == "backupFile" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.BackupFileAttr = &parsed
			continue
		}
		if attr.Name.Local == "saveExternalLinkValues" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.SaveExternalLinkValuesAttr = &parsed
			continue
		}
		if attr.Name.Local == "updateLinks" {
			m.UpdateLinksAttr.UnmarshalXMLAttr(attr)
			continue
		}
		if attr.Name.Local == "showObjects" {
			m.ShowObjectsAttr.UnmarshalXMLAttr(attr)
			continue
		}
		if attr.Name.Local == "filterPrivacy" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.FilterPrivacyAttr = &parsed
			continue
		}
		if attr.Name.Local == "showInkAnnotation" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.ShowInkAnnotationAttr = &parsed
			continue
		}
		if attr.Name.Local == "allowRefreshQuery" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.AllowRefreshQueryAttr = &parsed
			continue
		}
		if attr.Name.Local == "publishItems" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.PublishItemsAttr = &parsed
			continue
		}
		if attr.Name.Local == "checkCompatibility" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.CheckCompatibilityAttr = &parsed
			continue
		}
		if attr.Name.Local == "autoCompressPictures" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.AutoCompressPicturesAttr = &parsed
			continue
		}
		if attr.Name.Local == "refreshAllConnections" {
			parsed, err := strconv.ParseBool(attr.Value)
			if err != nil {
				return err
			}
			m.RefreshAllConnectionsAttr = &parsed
			continue
		}
		if attr.Name.Local == "defaultThemeVersion" {
			parsed, err := strconv.ParseUint(attr.Value, 10, 32)
			if err != nil {
				return err
			}
			pt := uint32(parsed)
			m.DefaultThemeVersionAttr = &pt
			continue
		}
	}
	// skip any extensions we may find, but don't support
	for {
		tok, err := d.Token()
		if err != nil {
			return fmt.Errorf("parsing CT_WorkbookPr: %s", err)
		}
		if el, ok := tok.(xml.EndElement); ok && el.Name == start.Name {
			break
		}
	}
	return nil
}

// Validate validates the CT_WorkbookPr and its children
func (m *CT_WorkbookPr) Validate() error {
	return m.ValidateWithPath("CT_WorkbookPr")
}

// ValidateWithPath validates the CT_WorkbookPr and its children, prefixing error messages with path
func (m *CT_WorkbookPr) ValidateWithPath(path string) error {
	if err := m.ShowObjectsAttr.ValidateWithPath(path + "/ShowObjectsAttr"); err != nil {
		return err
	}
	if err := m.UpdateLinksAttr.ValidateWithPath(path + "/UpdateLinksAttr"); err != nil {
		return err
	}
	return nil
}
