/*
 * Copyright 2016 Freescale Semiconductor
 * Copyright 2016-2017 NXP
 * To be used with MCUXpresso Config Tools under its Software License Agreement.
 */

// This object generate content of H file. The content is affected by generating C file.
var ClockConfigH = {
  // Output writer
  writer: null,
  
  // Status "is extern mcg_config_t generated". generate() initialize to false. C file generating script can set to true.
  isMcgConfigExtern: new Object(),
  // Status "is extern mcglite_config_t generated". generate() initialize to false. C file generating script can set to true.
  isMcgliteConfigExtern: new Object(),
  // Status "is extern sim_clock_config_t generated". generate() initialize to false. C file generating script can set to true.
  isSimConfigExtern: new Object(),
  // Status "is extern osc_config_t generated". generate() initialize to false. C file generating script can set to true.
  isOscConfigExtern: new Object(),
  
  // references on define block instances for "common" and for each configuration
  defineBlockH: new Object(),
  // references on define block positions for "common" and for each configuration
  defineBlockHPosition: new Object(),
  // references on extern mcg_config_t places for each configuration
  mcgConfigExternPosition: new Object(),
  // references on extern mcglite_config_t places for each configuration
  mcgliteConfigExternPosition: new Object(),
  // references on extern sim_clock_config_t places for each configuration
  simConfigExternPosition: new Object(),
  // references on extern osc_config_t places for each configuration
  oscConfigExternPosition: new Object(),
  
  // generate h file content and create insertions for definitions
  generate: function(writer) {
    // safe output writer
    this.writer = writer;
    
/*  
    HWriter.write(CommonHeaderText());
    HWriter.write("");
*/
    HWriter.writeLines([
    "/***********************************************************************************************************************",
    " * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file",
    " * will be overwritten if the respective MCUXpresso Config Tools is used to update this file.",
    " **********************************************************************************************************************/",
    "",
    "#ifndef _CLOCK_CONFIG_H_",
    "#define _CLOCK_CONFIG_H_",
    "",
    "#include \"fsl_common.h\"",
    "",
    ]);
    // Common definitions
    this.defineBlockHPosition["common"] = HWriter.write(null); 
    HWriter.writeLines(OutputUtils.getDefinitionIntro(), this.defineBlockHPosition["common"]);
    this.defineBlockH["common"] = new DefineBlock(); 
    var theSame = HwAbstr.isSettingSameInAllConfigurations("OSC.OSC.outFreq", "osc", "asInteger");
    if (theSame != null && theSame) {
      var values = HwAbstr.getSettingValuesForAllConfigurations("OSC.OSC.outFreq", "osc", "asInteger");
      this.defineBlockH["common"].addDefine("BOARD_XTAL0_CLK_HZ", values[0], "Board xtal0 frequency in Hz");
    }
    if (HwAbstr.hasRtcOwnOscillator()) {  
      var theSame = HwAbstr.isSettingSameInAllConfigurations("RTC.RTC32kHz.outFreq", "rtcOsc", "asInteger");
      if (theSame != null && theSame) {
        var values = HwAbstr.getSettingValuesForAllConfigurations("RTC.RTC32kHz.outFreq", "rtcOsc", "asInteger");
        this.defineBlockH["common"].addDefine("BOARD_XTAL32K_CLK_HZ", values[0], "Board RTC xtal frequency in Hz");
      }
    }
    else {
      if (HwAbstr.clockElementExist(Gen.configs[0], "rtcClkIn")) {
        var theSame = HwAbstr.isSettingSameInAllConfigurations("SIM.RTC_CLK_EXT_IN.outFreq", "rtcClkIn", "asInteger");
        if (theSame != null && theSame) {
          var values = HwAbstr.getSettingValuesForAllConfigurations("SIM.RTC_CLK_EXT_IN.outFreq", "rtcClkIn", "asInteger");
          this.defineBlockH["common"].addDefine("BOARD_XTAL32K_CLK_HZ", values[0], "Board RTC xtal frequency in Hz");
        }
      }
    }
    
    HWriter.writeLines([
    '/*******************************************************************************',
    ' ************************ BOARD_InitBootClocks function ************************',
    ' ******************************************************************************/',
    '',
    '#if defined(__cplusplus)',
    'extern "C" {',
    '#endif /* __cplusplus*/',
    '',
    '/*!',
    ' * @brief This function executes default configuration of clocks.',
    ' *',
    ' */',
    'void BOARD_InitBootClocks(void);',
    '',
    '#if defined(__cplusplus)',
    '}',
    '#endif /* __cplusplus*/',
    '']);

    // generate the header part for each configuration 
    for (var cfgIndex = 0; cfgIndex < Gen.configs.length; cfgIndex++) {
      var cfg = Gen.configs[cfgIndex];
      var configID = Gen.getConfigID(cfg);
      var configName = cfg.getName();
      // clear status "is extern mcg_config_t generated"
      this.isMcgConfigExtern[configID] = false;
      // clear status "is extern mcglite_config_t generated"
      this.isMcgliteConfigExtern[configID] = false;
      // clear status "is extern sim_clock_config_t generated"
      this.isSimConfigExtern[configID] = false;
      // clear status "is extern osc_config_t generated"
      this.isOscConfigExtern[configID] = false;

      // write configuration introduction
      HWriter.writeLines(OutputUtils.getConfigurationIntro(cfg));
      // write definition introduction
      HWriter.writeLines(OutputUtils.getDefinitionIntro(cfg));

      this.defineBlockHPosition[configID] = HWriter.write(null); 
      // create block instance of #defines 
      this.defineBlockH[configID] = new DefineBlock();
      SDKMapper.setHWriterDefineContainer = this.defineBlockH[configID];   
      tmp = SDKMapper.getFieldValue(cfg, "coreClock");
      if (tmp != null) {
        this.defineBlockH[configID].addDefine(configID.toUpperCase() + "_CORE_CLOCK", tmp.value, tmp.description);
      }
  
      // allocate place for extern mcg_config_t 
      this.mcgConfigExternPosition[configID] = HWriter.write(null);
      // allocate place for extern mcglite_config_t 
      this.mcgliteConfigExternPosition[configID] = HWriter.write(null);
      // allocate place for extern sim_clock_config_t 
      this.simConfigExternPosition[configID] = HWriter.write(null);
      // allocate place for extern osc_config_t 
      this.oscConfigExternPosition[configID] = HWriter.write(null);
      HWriter.line("");  

      // write api introduction
      HWriter.writeLines(OutputUtils.getApiIntro(cfg));
      HWriter.writeLines([
      "#if defined(__cplusplus)",
      "extern \"C\" {",
      "#endif /* __cplusplus*/"]);
      HWriter.write("");
      HWriter.writeLines([
      "/*!",
      " * @brief This function executes configuration of clocks.",
      " *",
      " */"]);
      HWriter.write("void " + Gen.getConfigID(Gen.configs[cfgIndex]) + "(void);");
      HWriter.writeLines([
      "",
      "#if defined(__cplusplus)",
      "}",
      "#endif /* __cplusplus*/",
      "",
      ]);
    }
    HWriter.writeLines([
    "#endif /* _CLOCK_CONFIG_H_ */",
    "",
    ]);
  },
  
  // complete h file content, e.g. definition insertion
  complete: function(){
    // write common define block
    HWriter.writeLines(this.defineBlockH["common"].getDefineBlock().concat(""), this.defineBlockHPosition["common"]);
    for (var cfgIndex = 0; cfgIndex < Gen.configs.length; cfgIndex++) {
      var cfg = Gen.configs[cfgIndex];
      var configID = Gen.getConfigID(cfg);
      var configName = cfg.getName();
      // write common define block
      HWriter.writeLines(this.defineBlockH[configID].getDefineBlock().concat(""), this.defineBlockHPosition[configID]);
      // extern mcg_config_t
      if (this.isMcgConfigExtern[configID]) {
        HWriter.writeLines([
        "/*! @brief MCG set for " + configName + " configuration.",
        " */",
        ], this.mcgConfigExternPosition[configID]);
        HWriter.write("extern const mcg_config_t mcgConfig_" + configID + ";", this.mcgConfigExternPosition[configID]);
      }
      // extern mcg_config_t
      if (this.isMcgliteConfigExtern[configID]) {
        HWriter.writeLines([
        "/*! @brief MCG lite set for " + configName + " configuration.",
        " */",
        ], this.mcgliteConfigExternPosition[configID]);
        HWriter.write("extern const mcglite_config_t mcgliteConfig_" + configID + ";", this.mcgliteConfigExternPosition[configID]);
      }
      // extern sim_clock_config_t
      if (this.isSimConfigExtern[configID]) {
        HWriter.writeLines([
        "/*! @brief SIM module set for " + configName + " configuration.",
        " */"
        ], this.simConfigExternPosition[configID]);
        HWriter.write("extern const sim_clock_config_t simConfig_" + configID + ";", this.simConfigExternPosition[configID]);
      }
      // extern osc_config_t
      if (this.isOscConfigExtern[configID]) {
        HWriter.writeLines([
        "/*! @brief OSC set for " + configName + " configuration.",
        " */"
        ], this.oscConfigExternPosition[configID]);
        HWriter.write("extern const osc_config_t oscConfig_" + configID + ";", this.oscConfigExternPosition[configID]);
      }
    }
  },
}