## @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 self.SpecialComments.has_key(Type):           
                    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 == None:
        ErrorCode = ToolError.FORMAT_INVALID
    if LineInfo == None:
        LineInfo = ['', -1, '']
    Logger.Error("InfParser", 
                 ErrorCode, 
                 Message=Message, 
                 File=LineInfo[0], 
                 Line=LineInfo[1],
                 ExtraData=LineInfo[2], 
                 RaiseError=RaiseError)