<!DOCTYPE html>
<html ng-app="inheritApp">

<head lang="en">
    <meta charset="UTF-8">
    <title>Inherit3</title>
</head>

<body>
<div ng-controller="MainCtrl_1 as mc">
    Input:
    <input type="text" ng-model="mc.myText" />

    <p>Parent data: {{mc.myText}}</p>
    <p>Child data: {{mc.myText2}}</p>
    <p>Parent array: {{mc.colors}}</p>

    <input type="button" value="Base/Base" ng-click="mc.parentParentAlert()" />
    <input type="button" value="Base/Child" ng-click="mc.parentChildAlert()" />
    <input type="button" value="Child/Child" ng-click="mc.childChildAlert()" />
</div>
<hr/>
<div ng-controller="MainCtrl_2 as mc">
    Input:
    <input type="text" ng-model="mc.myText" />

    <p>Parent data: {{mc.myText}}</p>
    <p>Child data: {{mc.myText2}}</p>
    <p>Parent array: {{mc.colors}}</p>

    <input type="button" value="Base/Base" ng-click="mc.parentParentAlert()" />
    <input type="button" value="Base/Child" ng-click="mc.parentChildAlert()" />
    <input type="button" value="Child/Child" ng-click="mc.childChildAlert()" />
</div>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
<script>
    "use strict";
    // Build modules and reveal only pointers to what we want to be visible
    // Globals contain methods and variables that we can use everywhere.
    var globalUtils = (function(window, undefined) {
        "use strict";
        var gmap = {};
        // Parasitic Combination Inheritance from Professional JavaScript for Web Developers (Kindle Location 7328). John Wiley and Sons. Kindle Edition.
        function InheritPrototype(subType, superType) {
            var prototype = Object(superType.prototype); // create object
            prototype.constructor = subType; // augment object
            subType.prototype = prototype; // assign object
        }

        return {
            inheritPrototype: InheritPrototype,
            appMap: gmap
        };
    }).call(window);


    // The base 'class' for this example
    globalUtils.appMap.baseLogic = (function(window, globalU, undefined) {

        function ParentFn(globalsService) {
            this.myText = "Hello, Parent World";
            this.myText2 = globalsService.getHello();
            this.colors = ["red", "blue", "green"];
            this.parentParentAlert = function() {
                alert("ParentFn.makeAlert(): " + this.myText2);
            };
        }

        return {
            parentPtr: ParentFn
        }
    })(window, globalUtils);


    // items that will be used by Angular. In this case a 'child class' and
    // a function that we'll put in a factory
    globalUtils.appMap.myLogic = (function(window, base, globalU, undefined) {
        function ChildFn2(globalService) {
            base.call(this, globalService);
            globalU.inheritPrototype(this, base);
            this.childText = "Hello Child World"

            this.parentChildAlert = function() {
                var str = "ChildFn2.parentChildAlert(): ";
                alert(str + this.myText);
            };

            this.childChildAlert = function() {
                alert("ChildFn2.childChildAlert: " + this.childText);
            };
        }

        function ChildFn3(globalService) {
            ChildFn2.call(this, globalService);
            globalU.inheritPrototype(this, ChildFn2);
        }

        function ChildFn4(globalService) {
            ChildFn2.call(this, globalService);
            globalU.inheritPrototype(this, ChildFn2);
            this.colors.push('black');
        }


        function FactoryFn() {
            return {
                getHello: function() {
                    return "GlobalService.getHello";
                }
            };
        }

        return {
            childPtr2: ChildFn2,
            childPtr3: ChildFn3,
            childPtr4: ChildFn4,
            factoryPtr: FactoryFn
        }

    })(window, globalUtils.appMap.baseLogic.parentPtr, globalUtils);

    // The Angular code
    (function(angular, ml, undefined) {
        angular.module('globalsApp', [])
                .factory('GlobalsService', [ml.factoryPtr]);
    })(angular, globalUtils.appMap.myLogic);

    // The Angular code
    (function(angular, ml, undefined) {
        angular.module('inheritApp', ['globalsApp'])
                .controller('MainCtrl_1', ['GlobalsService', ml.childPtr3])
                .controller('MainCtrl_2', ['GlobalsService', ml.childPtr4]);
    })(angular, globalUtils.appMap.myLogic);
</script>

</body>

</html>