class AssetService {

    boolean transactional = false

    /**
    * Determines and returns a possible list of asset sub items.
    * @returns A list of the possible assetSubItems.
    */
    def possibleAssetSubItems() {
        def criteria = AssetSubItem.createCriteria()
        def possibleAssetSubItems = criteria.list() {
            isNull("parentItem")
        }
    }

    def create(params) {
        def result = [:]
        def fail = { Map m ->
            result.error = [ code: m.code, args: ["Asset", params.id] ]
            return result
        }

        result.assetInstance = new Asset()
        result.assetInstance.properties = params

        // success
        return result
    }

    def copy(params) {
        def result = [:]
        def fail = { Map m ->
            result.error = [ code: m.code, args: ["Asset", params.id] ]
            return result
        }

        result.assetToCopy = Asset.get(params.assetToCopy?.id)

        if(!result.assetToCopy)
            return fail(code: "asset.copy.asset.required")

        result.assetInstance = new Asset(name: result.assetToCopy.name,
                                                            description: result.assetToCopy.description,
                                                            section: result.assetToCopy.section)

        result.assetInstance.properties = params

        // success
        return result
    }

    def save(params) {
        def result = [:]
        def fail = { Map m ->
            if(result.assetInstance && m.field) 
                result.assetInstance.errors.rejectValue(m.field, m.code)
            result.error = [ code: m.code, args: ["Asset", params.id] ]
            return result
        }

        result.assetInstance = new Asset(params)

        if(result.assetInstance.hasErrors() || !result.assetInstance.save(flush: true))
            return fail(code:"default.create.failure")

        // success
        return result
    }

    def saveCopy(params) {
        Asset.withTransaction { status ->
            def result = [:]

            def fail = { Map m ->
                status.setRollbackOnly()
                if(result.assetInstance && m.field)
                    result.assetInstance.errors.rejectValue(m.field, m.code)
                result.error = [ code: m.code, args: ["Asset", params.id] ]
                return result
            }

            result.assetToCopy = Asset.get(params.assetToCopy?.id)
            if(!result.assetToCopy)
                return fail(code:"default.not.found")

            if(!params.copyMethod)
                fail(code:"asset.copy.method.required")

            result.assetInstance =  new Asset(params)

            if(result.assetInstance.hasErrors() || !result.assetInstance.save())
                return fail(code:"default.create.failure")

            def assetSubItemInstance1

            // Copy subItems from level 2 and bellow.
            def copyAssetSubItem = { assetSubItemToCopy, parentItem ->
                def assetSubItemInstance = new AssetSubItem(name: assetSubItemToCopy.name,
                                                                                            description: assetSubItemToCopy.description,
                                                                                            parentItem: parentItem)

                if(assetSubItemInstance.hasErrors() || !assetSubItemInstance.save())
                    return fail(field:"subItems", code:"default.create.failure")

                def i = 0
                for(assetSubItem in assetSubItemToCopy.subItems) {
                    call(assetSubItem, assetSubItemInstance)
                    // Protect against endless recurrsion.
                    i++
                    if(i > 100)
                        fail(code:"default.create.failure")
                    // Stop if an error is flagged.
                    if(result.error)
                        break
                }
            } //copyAssetSubItem

            // Copy the 1st level of subItems.
            def copyAssetSubItem1 = { assetSubItemToCopy ->
                assetSubItemInstance1 = new AssetSubItem(name: assetSubItemToCopy.name,
                                                                                        description: assetSubItemToCopy.description,
                                                                                        asset: result.assetInstance)

                if(assetSubItemInstance1.hasErrors() || !assetSubItemInstance1.save())
                    return fail(field:"assetSubItems", code:"default.create.failure")

                result.assetInstance.addToAssetSubItems(assetSubItemInstance1)

                def i = 0
                for(assetSubItem in assetSubItemToCopy.subItems) {
                    copyAssetSubItem(assetSubItem, assetSubItemInstance1)
                    // Protect against endless recurrsion.
                    i++
                    if(i > 100)
                        fail(code:"default.create.failure")
                    // Stop if an error is flagged.
                    if(result.error)
                        break
                }
            } //copyAssetSubItem1

            def linkAssetSubItem = { assetSubItemToLink ->
                result.assetInstance.addToAssetSubItems(assetSubItemToLink)
            }

            def i = 0
            for(assetSubItem in result.assetToCopy.assetSubItems) {

                if(params.copyMethod == "copy")
                    copyAssetSubItem1(assetSubItem)
                else
                    linkAssetSubItem(assetSubItem)
                // Protect against endless recurrsion.
                i++
                if(i > 100)
                    fail(code:"default.create.failure")
                // Stop if an error is flagged.
                if(result.error)
                    break
            }

            // Success or not.
            return result

        } //end withTransaction
    } // end saveCopySrvce

} // end class