## @file
# This file is used to define class objects of INF file miscellaneous. 
# Include BootMode/HOB/Event and others. It will consumed by InfParser. 
#
# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are licensed and made available 
# under the terms and conditions of the BSD License which accompanies this 
# distribution. The full text of the license may be found at 
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

'''
InfMisc
'''

import Logger.Log as Logger
from Logger import ToolError

from Library import DataType as DT
from Object.Parser.InfCommonObject import InfSectionCommonDef
from Library.Misc import Sdict

## 
# BootModeObject
#
class InfBootModeObject():
    def __init__(self):
        self.SupportedBootModes = ''
        self.HelpString = ''
        self.Usage = ''
            
    def SetSupportedBootModes(self, SupportedBootModes):
        self.SupportedBootModes = SupportedBootModes   
    def GetSupportedBootModes(self):
        return self.SupportedBootModes

    def SetHelpString(self, HelpString):
        self.HelpString = HelpString
    def GetHelpString(self):
        return self.HelpString    

    def SetUsage(self, Usage):
        self.Usage = Usage
    def GetUsage(self):
        return self.Usage
##
# EventObject
#
class InfEventObject():
    def __init__(self):
        self.EventType = ''
        self.HelpString = ''
        self.Usage = ''
            
    def SetEventType(self, EventType):
        self.EventType = EventType
    
    def GetEventType(self):
        return self.EventType
    
    def SetHelpString(self, HelpString):
        self.HelpString = HelpString
    def GetHelpString(self):
        return self.HelpString    
    
    def SetUsage(self, Usage):
        self.Usage = Usage
    def GetUsage(self):
        return self.Usage
##
# HobObject
#
class InfHobObject():
    def __init__(self):
        self.HobType = ''
        self.Usage = ''
        self.SupArchList = []
        self.HelpString = ''
        
    def SetHobType(self, HobType):
        self.HobType = HobType
    
    def GetHobType(self):
        return self.HobType
    
    def SetUsage(self, Usage):
        self.Usage = Usage
    def GetUsage(self):
        return self.Usage
    
    def SetSupArchList(self, ArchList):
        self.SupArchList = ArchList
    def GetSupArchList(self):
        return self.SupArchList
    
    def SetHelpString(self, HelpString):
        self.HelpString = HelpString
    def GetHelpString(self):
        return self.HelpString
    
##
# InfSpecialCommentObject
#    
class InfSpecialCommentObject(InfSectionCommonDef):
    def __init__(self):
        self.SpecialComments = Sdict()
        InfSectionCommonDef.__init__(self)
        
    def SetSpecialComments(self, SepcialSectionList = None, Type = ''):
        if Type == DT.TYPE_HOB_SECTION or \
           Type == DT.TYPE_EVENT_SECTION or \
           Type == DT.TYPE_BOOTMODE_SECTION:
            for Item in SepcialSectionList:
                if Type in self.SpecialComments:
                    ObjList = self.SpecialComments[Type]
                    ObjList.append(Item)
                    self.SpecialComments[Type] = ObjList
                else:
                    ObjList = []
                    ObjList.append(Item)
                    self.SpecialComments[Type] = ObjList
           
        return True
    
    def GetSpecialComments(self):
        return self.SpecialComments



## ErrorInInf
# 
# An encapsulate of Error for INF parser.
# 
def ErrorInInf(Message=None, ErrorCode=None, LineInfo=None, RaiseError=True):
    if ErrorCode is None:
        ErrorCode = ToolError.FORMAT_INVALID
    if LineInfo is None:
        LineInfo = ['', -1, '']
    Logger.Error("InfParser", 
                 ErrorCode, 
                 Message=Message, 
                 File=LineInfo[0], 
                 Line=LineInfo[1],
                 ExtraData=LineInfo[2], 
                 RaiseError=RaiseError)
