Imports System
Imports System.IO
Imports System.Drawing
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.HtmlControls

Imports Plumtree.Remote.Portlet
Imports Plumtree.Remote.PRC
Imports Plumtree.Remote.PRC.Content
Imports Plumtree.Remote.PRC.Content.DataEntryTemplate
Imports Plumtree.Remote.PRC.Content.Folder
Imports Plumtree.Remote.PRC.Content.Property
Imports Plumtree.Remote.PRC.Content.SelectionList
Imports Plumtree.Remote.PRC.Content.Item

Public Class DETSample
    Inherits System.Web.UI.Page

    Protected remoteSession As IRemoteSession
    Protected portletContext As IPortletContext
    Protected dataEntryTemplate As IDataEntryTemplate

#Region " Web Form Designer Generated Code "

    'This call is required by the Web Form Designer.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

    End Sub
    Protected WithEvents lblDETName As System.Web.UI.WebControls.Label
    Protected WithEvents pnlMain As System.Web.UI.WebControls.Panel
    Protected WithEvents lblMessage As System.Web.UI.WebControls.Label
    Protected WithEvents btnCreateItem As System.Web.UI.WebControls.Button

    'NOTE: The following placeholder declaration is required by the Web Form Designer.
    'Do not delete or move it.
    Private designerPlaceholderDeclaration As System.Object

    Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
        'CODEGEN: This method call is required by the Web Form Designer
        'Do not modify it using the code editor.
        InitializeComponent()
    End Sub

#End Region

    Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            portletContext = PortletContextFactory.CreatePortletContext(Request, Response)
            remoteSession = portletContext.GetRemotePortalSession()

            'Get the content factory.
            Dim contentFactory As IContentFactory = remoteSession.GetContentFactory()

            'Get the folder containing the data entry template.
            Dim folder As IFolder = RetrieveContentFolder(contentFactory)

            'Get the data entry template
            dataEntryTemplate = RetrieveDET(contentFactory, folder)

            'Put the name of the data entry template at the top of the form.
            lblDETName.Text = dataEntryTemplate.Name

            'Create input controls for data entry template.
            RenderDataEntryTemplate(dataEntryTemplate)

        Catch ex As Exception
            DisplayMessage("Exception: " + ex.Message)
        End Try

    End Sub

    ' <summary>
    ' Gets the Content Server folder used to store all Content
    ' Server objects for our application.
    ' <p>
    ' In this sample, we will create a new folder. In your
    ' real application you would likely have created the folder																										 * already and will need to query for it here.
    ' </summary>
    Public Shared Function RetrieveContentFolder(ByVal factory As IContentFactory) As IFolder
        ' Get a folder manager for working with Content Server folders.
        Dim folderManager As IFolderManager = factory.GetFolderManager()

        'Check to see if the folder has already been created
        Dim subFolder As IFolder = folderManager.GetFolderByPath("/VB.NET Web Example - DET")

        If (subFolder Is Nothing) Then
            'If the folder is not there we will create our own folder for the sample

            ' Get a reference to the root folder. It always exists.
            Dim rootFolder As IFolder = folderManager.GetRootFolder()

            ' Create a new folder.
            subFolder = folderManager.CreateFolder(rootFolder, "VB.NET Web Example - DET")
            subFolder.Store()
        End If

        Return subFolder
    End Function

    ' <summary>
    ' Gets the DET that defines what fields are present in each
    ' customer support incident.
    ' <p>
    ' In this sample, we will create a new DET. In your real
    ' application, this method would probably query for an existing Data Entry Template.																										 * existing DET.
    ' </summary>
    Public Shared Function RetrieveDET(ByVal factory As IContentFactory, ByVal folder As IFolder) As IDataEntryTemplate
        '
        ' A Data Entry Template object is a collection of
        ' property objects. Each property object represents
        ' a field in the records associated with the DET.
        '
        ' This sample uses all of the classes of properties
        ' available in Content Server. Each customer support
        ' incidents will have:
        '   (integer)         Incident ID
        '   (boolean)         If the incident has been resolved
        '   (float)           Incident severity rating
        '   (date)            Date the incident was opened
        '   (text line)       Customer name
        '   (item reference)  Link to other content item representing the customer
        '   (selection list)  The product the incident was reported in
        '   (text block)      Reported problem
        '   (file)            Logs of problem
        '   (image)           Screen shot of problem
        '

        ' Get manager objects needed for creating a DET.
        Dim detManager As IDataEntryTemplateManager = factory.GetDataEntryTemplateManager

        ' Check to see if the data entry template already exists
        Dim det As IDataEntryTemplate = detManager.GetDataEntryTemplate(folder, "Support Incident Data Entry Template")
        If (Not det Is Nothing) Then
            Return det
        End If

        Dim propertyManager As IPropertyManager = factory.GetPropertyManager
        Dim slManager As ISelectionListManager = factory.GetSelectionListManager

        ' Create a DET object.
        det = detManager.CreateDataEntryTemplate(folder, "Support Incident Data Entry Template")

        ' Add an integer property.
        Dim incident As IIntegerProperty = propertyManager.CreateIntegerProperty("Incident ID", "The ticket number for this incident.")
        det.AddProperty(incident)

        ' Add a boolean property
        Dim resolved As IBooleanProperty = propertyManager.CreateBooleanProperty("Resolved", "True if the incident has been closed false if it is still open.")
        det.AddProperty(resolved)

        ' Add a double property.
        Dim severity As IDoubleProperty = propertyManager.CreateDoubleProperty("Severity", "Percentage stating how severe the incident is.")
        det.AddProperty(severity)

        ' Add a date property.
        Dim opened As IDateProperty = propertyManager.CreateDateProperty("Date Opened", "The date and time the incident was reported.")
        det.AddProperty(opened)

        ' Add a text line property.
        '  Text lines are brief strings without newline characters.
        '  Use the text block property for storing longer strings.
        Dim customerName As ITextLineProperty = propertyManager.CreateTextLineProperty("Customer Name", "The name of the customer.")
        det.AddProperty(customerName)

        ' Add an item reference property.
        '  An item reference links to another content item. The
        '  content item does not have to be associated with the
        '  same DET. For example, we will link to a fictional
        '  content item representing the customer that is having
        '  the support problem which would be associated with
        '  a DET representing customers.
        '
        '  Not shown is the item collection property. It is
        '  similar to the item reference property, but links to
        '  multiple content items.
        Dim customerData As IItemReferenceProperty = propertyManager.CreateItemReferenceProperty("Customer Information", "Links to information about the customer such as the contact and their phone number.")
        det.AddProperty(customerData)

        ' Add a selection list property.
        '  A selection list is a defined set of choices of which
        '  one may be selected. This can be visualized as a
        '  drop down box.
        Dim selectionList As ISelectionList = Nothing
        Dim selectionLists() As ISelectionList = slManager.GetSelectionLists(folder)
        Dim sl As ISelectionList
        For Each sl In selectionLists
            If (sl.Name.Equals("Products Selection List")) Then
                selectionList = sl
            End If
        Next

        If (selectionList Is Nothing) Then
            Dim listValues() As String = {"Portal", "Search Server", "Collaboration Server", "Content Server", "Analytics"}
            selectionList = slManager.CreateSelectionList(folder, "Products Selection List", listValues)
            selectionList.Store()
        End If

        Dim products As ISelectionListProperty = propertyManager.CreateSelectionListProperty("Product", "The product which the support incident is opened against", SelectionList)
        det.AddProperty(products)

        ' Add a text block property.
        '  Text block properties are used to store long strings
        '  that can span many lines. For short strings contained
        '  on only one line, use the text line property instead.
        Dim description As ITextBlockProperty = propertyManager.CreateTextBlockProperty("Incident Description", "A writeup summarizing the problem the customer is experiencing.")
        det.AddProperty(description)

        ' Add a file property.
        Dim log As IFileProperty = propertyManager.CreateFileProperty("Log File", "A log file taken while the problem occurred.")
        det.AddProperty(log)

        ' Add an image property.
        Dim screenShot As IImageProperty = propertyManager.CreateImageProperty("Screen Shot", "A screen shot of the problem.")
        det.AddProperty(screenShot)

        ' Actually store the DET and all the properties associated with it.
        det.Store()

        Return det
    End Function

    ' <summary>
    ' Create all the controls for a given Data Entry Template.  The type of
    ' control depends on the type of property.
    ' </summary>
    ' <param name="dataEntryTemplate"></param>
    Private Sub RenderDataEntryTemplate(ByVal dataEntryTemplate As IDataEntryTemplate)
        Dim table As Table = New Table
        table.ID = "Main DET Table"

        'Add TextBox to enter Content Item Name
        Dim textBox As TextBox = New TextBox
        textBox.ID = "Content Item Name"
        AddTableRow(table, "Content Item Name", textBox, "")

        'Loop through all the properties and add them to the table based on property type
        Dim allProperties() As IBaseProperty = dataEntryTemplate.GetAllProperties
        Dim prop As IBaseProperty
        For Each prop In allProperties
            'Check for different types of properties
            If TypeOf prop Is IBooleanProperty Then
                Dim boolProp As IBooleanProperty = DirectCast(prop, IBooleanProperty)
                Dim checkBox As CheckBox = New CheckBox
                checkBox.ID = prop.Name

                AddTableRow(table, prop.DisplayName, checkBox, prop.Description)
            End If

            If TypeOf prop Is IDateProperty Then
                Dim dateProp As IDateProperty = DirectCast(prop, IDateProperty)

                textBox = New TextBox
                textBox.ID = prop.Name

                AddTableRow(table, prop.DisplayName, textBox, prop.Description)
            End If

            If TypeOf prop Is IDoubleProperty Then
                Dim doubleProp As IDoubleProperty = DirectCast(prop, IDoubleProperty)
                textBox = New TextBox
                textBox.ID = prop.Name

                AddTableRow(table, prop.DisplayName, textBox, prop.Description)
            End If

            If TypeOf prop Is IFileProperty Then
                Dim fileProp As IFileProperty = DirectCast(prop, IFileProperty)
                'The HtmlInputFile control requires the 2.2 .NET WebControls to work properly
                'Also make sure the Html Form has the attribute enctype=multipart/form-data
                Dim inputFile As HtmlInputFile = New HtmlInputFile
                inputFile.ID = prop.Name

                'Using an HtmlInputFile control will take us out of the portal when there
                'is a postback.  We could use something like portletContext.GetResponse().ReturnToPortal()
                'to get back to the portal after the postback. For now we'll omit the control for simplicity.

                'AddTableRow(table, prop.DisplayName, inputFile, prop.Description)
                AddTableRow(table, prop.DisplayName, New LiteralControl(""), prop.Description)
            End If

            If TypeOf prop Is IImageProperty Then
                Dim imageProp As IImageProperty = DirectCast(prop, IImageProperty)
                'The HtmlInputFile control requires the 2.2 .NET WebControls to work properly
                'Also make sure the Html Form has the attribute enctype=multipart/form-data
                Dim inputFile As HtmlInputFile = New HtmlInputFile
                inputFile.ID = prop.Name

                'Using an HtmlInputFile control will take us out of the portal when there
                'is a postback.  We could use something like portletContext.GetResponse().ReturnToPortal()
                'to get back to the portal after the postback. For now we'll omit the control for simplicity.

                'AddTableRow(table, prop.DisplayName, inputFile, prop.Description)
                AddTableRow(table, prop.DisplayName, New LiteralControl(""), prop.Description)
            End If

            If TypeOf prop Is IIntegerProperty Then
                Dim integerProp As IIntegerProperty = DirectCast(prop, IIntegerProperty)
                textBox = New TextBox
                textBox.ID = prop.Name

                AddTableRow(table, prop.DisplayName, textBox, prop.Description)
            End If

            If TypeOf prop Is IItemReferenceProperty Then
                Dim itemRefProp As IItemReferenceProperty = DirectCast(prop, IItemReferenceProperty)
                'We could query for valid content items and display them in a control
                'or display content items based on some other business logic.
                'For the sample we'll leave this blank.
                AddTableRow(table, prop.DisplayName, New LiteralControl(""), prop.Description)
            End If

            If TypeOf prop Is ISelectionListProperty Then
                Dim selectionListProp As ISelectionListProperty = DirectCast(prop, ISelectionListProperty)
                Dim dropDown As DropDownList = New DropDownList
                dropDown.ID = prop.Name

                Dim selectionList As ISelectionList = selectionListProp.GetSelectionList()
                Dim values() As String = selectionList.GetValues()
                Dim val As String
                For Each val In values
                    dropDown.Items.Add(val)
                Next
                AddTableRow(table, prop.DisplayName, dropDown, prop.Description)
            End If

            If TypeOf prop Is ITextBlockProperty Then
                Dim textBlockProp As ITextBlockProperty = DirectCast(prop, ITextBlockProperty)

                Dim textArea As HtmlTextArea = New HtmlTextArea
                textArea.ID = prop.Name

                AddTableRow(table, prop.DisplayName, textArea, prop.Description)
            End If

            If TypeOf prop Is ITextLineProperty Then
                Dim textLineProp As ITextLineProperty = DirectCast(prop, ITextLineProperty)

                textBox = New TextBox
                textBox.ID = prop.Name

                AddTableRow(table, prop.DisplayName, textBox, prop.Description)
            End If
        Next

        'Add the table to the main panel
        pnlMain.Controls.Add(table)
    End Sub

    ' <summary>
    ' Add a content property row to an HTML table
    ' </summary>
    ' <param name="table">Table to add row to</param>
    ' <param name="name">Name of property being added</param>
    ' <param name="control">Input control for this property</param>
    ' <param name="description">Description of property</param>
    Private Shared Sub AddTableRow(ByVal table As Table, ByVal name As String, ByVal control As Control, ByVal description As String)
        Dim row As TableRow = New TableRow
        Dim cell As TableCell = New TableCell

        'Add Name to first column of first row
        cell.Text = name
        cell.Font.Bold = True
        row.Cells.Add(cell)

        'Add Control to second column of first row
        cell = New TableCell
        cell.Controls.Add(control)
        row.Cells.Add(cell)

        'Add first row to table
        table.Rows.Add(row)

        'add description to second column of second row so
        'it is under the control
        row = New TableRow
        cell = New TableCell

        row.Cells.Add(cell)
        cell = New TableCell

        cell.Text = description
        row.Cells.Add(cell)

        table.Rows.Add(row)
    End Sub

    ' <summary>
    ' Displays an error message in red
    ' </summary>
    ' <param name="message">message to display</param>
    Private Sub DisplayMessage(ByVal message As String)
        lblMessage.Text = message
        lblMessage.ForeColor = Color.Red
    End Sub

    ' <summary>
    ' Create button click event handler
    ' </summary>
    Private Sub btnCreateItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCreateItem.Click
        Try
            'Get the Content Item Manager
            Dim contentFactory As IContentFactory = remoteSession.GetContentFactory()
            Dim contentItemManager As IContentItemManager = contentFactory.GetContentItemManager()

            ' Create a new Content Item.
            Dim contentItemName As String = CType(pnlMain.FindControl("Content Item Name"), TextBox).Text
            Dim contentItem As IContentItem = contentItemManager.CreateContentItem(dataEntryTemplate.GetContainingFolder, contentItemName, dataEntryTemplate)

            ' Assign the fields of the content item.
            ' Each field is defined by the DET corresponding to the content item.
            Dim props() As IBaseProperty = dataEntryTemplate.GetAllProperties

            Dim table As Table = CType(pnlMain.FindControl("Main DET Table"), Table)

            Dim row As TableRow
            For Each row In table.Rows
                Dim control As Control
                For Each control In row.Cells(1).Controls
                    'NOTE: Even though RenderDataEntryTemplate dynamically creates
                    'controls for any data entry template, this method has been hard-coded 
                    'for the data entry template we've created in RetrieveDET for clarity.
                    Select Case control.ID
                        Case "Incident ID"
                            contentItem.SetIntegerPropertyValue(props(0), Convert.ToInt32(CType(control, TextBox).Text))

                        Case "Resolved"
                            contentItem.SetBooleanPropertyValue(props(1), CType(control, CheckBox).Checked)

                        Case "Severity"
                            contentItem.SetDoublePropertyValue(props(2), Convert.ToDouble(CType(control, TextBox).Text))

                        Case "Date Opened"
                            contentItem.SetDatePropertyValue(props(3), DateTime.Parse(CType(control, TextBox).Text))

                        Case "Customer Name"
                            contentItem.SetTextLinePropertyValue(props(4), CType(control, TextBox).Text)

                        Case "Customer Information"
                            'Dim customer As IContentItem = contentItemManager.GetContentItem(dataEntryTemplate.GetContainingFolder, "Customer X")
                            'contentItem.SetItemReferencePropertyValue(props(5), customer)

                        Case "Product"
                            contentItem.SetSelectionListPropertyValue(props(6), CType(control, DropDownList).SelectedValue)

                        Case "Incident Description"
                            contentItem.SetTextBlockPropertyValue(props(7), CType(control, HtmlTextArea).Value)

                        Case "Log File"
                            'The HtmlInputFile control requires the 2.2 .NET WebControls to work properly
                            'Also make sure the Html Form has the attribute enctype=multipart/form-data
                            Dim postedLogFile As HttpPostedFile = CType(control, HtmlInputFile).PostedFile
                            If (Not postedLogFile Is Nothing) Then
                                Dim fileName As String = Path.GetFileName(postedLogFile.FileName)
                                If (Not fileName Is "") Then
                                    contentItem.SetFilePropertyValue(props(8), fileName, postedLogFile.InputStream)
                                End If
                            End If

                        Case "Screen Shot"
                            'The HtmlInputFile control requires the 2.2 .NET WebControls to work properly
                            'Also make sure the Html Form has the attribute enctype=multipart/form-data
                            Dim postedScreenFile As HttpPostedFile = CType(control, HtmlInputFile).PostedFile
                            If (Not postedScreenFile Is Nothing) Then
                                Dim fileName As String = Path.GetFileName(postedScreenFile.FileName)
                                If (Not fileName Is "") Then
                                    contentItem.SetImagePropertyValue(props(9), fileName, postedScreenFile.InputStream)
                                End If
                            End If
                    End Select
                Next
            Next

            'Store the content Item
            contentItemManager.CheckInItem(contentItem, "Created by DET Sample Portlet")

            'Display a message about the new content item
            DisplayMessage("Content Item " + contentItemName + " Created")

        Catch ex As Exception
            DisplayMessage("Exception: " + ex.Message)
        End Try
    End Sub
End Class
